Specify docs

API reference

Send server events over HTTP from any language.

Use the HTTP API to send server events from a backend that can't use the Node.js SDK. It records the same events as the SDK's capture().

Identify in the browser too

A server event only counts for a user your site has identified with the browser SDK. Pass the same user ID in both places. Wallet addresses are the exception: they count from the server on their own.

Endpoint

POST https://spfsrv.com/v1/events

Authentication

HeaderValueRequired
Content-Typeapplication/jsonYes
x-api-keyYour advertiser key, which starts with sak_Yes

Request

Body

{
  "source": "server",
  "identity": "user_8f3a2c",
  "events": [
    {
      "name": "purchase",
      "dedupeKey": "order_1042"
    }
  ]
}

Parameters

ParameterTypeRequiredDescription
sourcestringYesAlways "server"
identitystringYesThe user ID your site passes to identify(), or a wallet address
eventsobject[]Yes1 to 50 events for this identity
events[].namestringYesThe event name, such as purchase
events[].dedupeKeystringNoYour own ID for this event, such as an order ID, up to 256 characters. Send one with every event
events[].urlstringNoThe page where the event happened, as an absolute URL

Specify rejects a body with any other field, and a body larger than 16 KiB.

Identity

  • A wallet address is 0x followed by 40 hexadecimal characters, in any case.
  • A user ID can't be blank, contain @, start with 0x, or be longer than 256 bytes. Use the ID your app gives the user, not their email address.

Response

Every response has an empty body.

CodeMeaningWhat to do
200RecordedNothing
400Invalid bodyCheck it against the parameters. Don't retry
401Invalid, revoked or unknown advertiser keyCheck the key. Don't retry
429Too many events at onceRetry
503Specify is temporarily unavailableRetry

Avoid double counting

Send a dedupeKey with every event. Events with the same name and dedupeKey count once, so retries and repeated webhooks are safe. Without one, every request counts, including a retry of a request Specify already recorded.

For an event that happens once per user, such as passing KYC, the user ID works as the dedupeKey.

Retries

Give each request a 5 second timeout. After a timeout, a network error, a 429 or a 5xx, retry twice: after 1 second, then after 2 seconds.

If the event still isn't recorded, log it and continue, so a problem on Specify's side can't break your handler.


Examples

Each example sends one event, retries as above, and logs a failure without raising it.

curl -X POST https://spfsrv.com/v1/events \
  -H "Content-Type: application/json" \
  -H "x-api-key: $SPECIFY_ADVERTISER_KEY" \
  -w "%{http_code}\n" \
  -d '{
    "source": "server",
    "identity": "user_8f3a2c",
    "events": [{ "name": "purchase", "dedupeKey": "order_1042" }]
  }'

Check it works

Send an event with a development key. A 200 means Specify accepted it, and the event appears in the event log on the Integration page within a few seconds. Development events never count towards your results.

When you're ready to go live, replace the development key with a production key.

Next steps

On this page