> ## Documentation Index
> Fetch the complete documentation index at: https://docs.serialized.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a Price Webhook

> Register the HTTPS endpoint we call when a token's price crosses your levels, optionally with its first triggers. Free.

`POST /v1/webhook/price` · **Free**

Creates a price webhook: the `callbackUrl` we call, the `secret` that signs every message, and optionally its first `triggers` (up to 1,000, on up to 100 distinct tokens). Give it your own `id`, or omit it and we generate one (`wh_` + 16 hex characters). Omit `secret` and we generate one (`whsec_…`): it is in this response only, keep it. A new webhook answers 201.

Creating an id you already have adds the triggers to it (`created: false`, status 200), as long as `callbackUrl` is the same, and `secret` and `name` too when you send them; a different value answers `400` on that field and nothing is written. Change them with [`/endpoint`](https://docs.serialized.xyz/endpoints/price-webhook-endpoint).

Each trigger is `{ "id"?, "name"?, "chain", "address", "priceUsd": { "gt" | "gte" | "lt" | "lte" | "eq": "<level>" } }`, the level in USD, or the same with `priceNative`, the level in the native coin of the chain ([conditions](https://docs.serialized.xyz/endpoints/price-webhooks.md#conditions), [USD or native](https://docs.serialized.xyz/endpoints/price-webhooks.md#usd-or-native)). `armed` lists the triggers armed by this call with their `direction`, `alreadyIn` those already there with the same condition, `rejected` the others with their index and error. Free; your account must be able to pay for the triggers it arms (1 credit per trigger sent to your URL).

> [!NOTE]
>
> At most 1,000 active triggers across your price webhooks (contact us for more) and 100 price webhooks per account. A call that would go past a cap is refused whole (`429``RATE_LIMITED`, `details.limit``priceTriggers` or `priceWebhooks`, with `max` and `current`): nothing is written.

```bash cURL theme={null}
curl -X POST 'https://api.serialized.xyz/v1/webhook/price' \
  -H 'Authorization: YOUR_API_KEY' -H 'Content-Type: application/json' \
  -d '{"id":"tpsl","callbackUrl":"https://example.com/hooks/price","name":"Orders","triggers":[{"id":"order-8812","name":"TP x2","chain":"solana","address":"DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263","priceUsd":{"gte":"0.000023"}},{"id":"order-8813","name":"SL","chain":"evm:8453","address":"0x4ed4e862860bed51a9570b96d89af5e1b0efefed","priceNative":{"lte":"0.0000009"}},{"chain":"evm:8453","address":"0x833589fcd6edb6e08f4c7c32d4f71b54bda02913","priceNative":{"gt":"0.001"}}]}'
```

```json Response theme={null}
{
  "data": {
    "id": "tpsl",
    "created": true,
    "secret": "whsec_2f9cN8kQx0b7VdLr4sYhTm1aWqE6uJpZ",
    "armed": [
      { "index": 0, "id": "order-8812", "direction": "gte" },
      { "index": 1, "id": "order-8813", "direction": "lte" }
    ],
    "alreadyIn": [],
    "rejected": [
      {
        "index": 2,
        "error": {
          "code": "INVALID_PARAM",
          "message": "Invalid parameter \"triggers[2].address\": price webhooks cover tokens, not native coins, their wrapped form or USD stablecoins",
          "details": { "param": "triggers[2].address", "reason": "stablecoin" }
        }
      }
    ]
  }
}
```


## OpenAPI

````yaml openapi.json POST /v1/webhook/price
openapi: 3.1.0
info:
  title: Serialized Data API
  description: >-
    On-chain data for trading apps - tokens, candles, token filters. Built on
    our own indexers. 18 EVM chains + Solana, live.
  version: 0.1.0
servers:
  - url: https://demo.serialized.xyz
    description: 'Demo: no key needed, read endpoints, rate-limited per IP'
  - url: https://api.serialized.xyz
    description: 'Production: your API key in the Authorization header'
security:
  - apiKey: []
  - {}
paths:
  /v1/webhook/price:
    post:
      summary: Create a Price Webhook
      description: >-
        Creates a price webhook: the `callbackUrl` we call, the `secret` that
        signs every message, and optionally its first `triggers`. Give it your
        own `id`, or omit it and we generate one (`wh_` + 16 hex characters).
        Omit `secret` and we generate one, returned in this response only.
        Creating an id you already have adds the triggers to it (`created:
        false`, status 200) when the URL, and the secret and name you send, are
        the same. Free; your account must be able to pay for the triggers it
        arms (1 credit per trigger sent to your URL).
      operationId: price-webhook-create
      requestBody:
        required: true
        content:
          application/json:
            schema:
              additionalProperties: false
              type: object
              required:
                - callbackUrl
              properties:
                id:
                  description: >-
                    1 to 64 characters among `A-Z a-z 0-9 _ . : -`, not starting
                    with a dot. Omitted: we generate one.
                  type: string
                  example: tpsl
                  x-default: tpsl
                callbackUrl:
                  description: >-
                    The URL we POST to: `https://` on port 443, a public host,
                    no credentials, at most 2,048 characters. Redirects are
                    never followed.
                  type: string
                  example: https://example.com/hooks/price
                  x-default: https://example.com/hooks/price
                secret:
                  description: >-
                    16 to 256 printable ASCII characters without spaces, used to
                    sign every message. Omitted: we generate one (`whsec_…`) and
                    return it once.
                  type: string
                name:
                  description: 1 to 128 characters, or null for none.
                triggers:
                  description: >-
                    1 to 1,000 triggers per call, on up to 100 distinct tokens:
                    `{ "id"?, "name"?, "chain", "address", "priceUsd": { "gt" |
                    "gte" | "lt" | "lte" | "eq": "<level>" } }`, the level in
                    USD, or the same with `priceNative`, the level in the native
                    coin of the chain (one of the two; a decimal string of at
                    most 32 characters, or a JSON number). An invalid trigger
                    comes back in `rejected` with its index; the others are
                    armed.
                  type: array
                  items: {}
      responses:
        '200':
          description: Standard `{ data, meta }` envelope.
components:
  securitySchemes:
    apiKey:
      type: apiKey
      name: Authorization
      in: header
      description: Your raw API key (not needed on the demo server).

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.