Any language
adscapi ships no per-language SDK. For Python, Ruby, Go, PHP, Rust, or anything else: deploy the hosted relay and POST one event, or shell out to the CLI from CI.
Option A — Hosted relay
The Cloudflare Worker in worker/ keeps platform secrets on the Worker. Callers only need a shared bearer token. One HTTP call fans out to every configured destination.
shell
cd worker npx wrangler secret put RELAY_AUTH_TOKEN npx wrangler secret put META_CAPI_TOKEN npx wrangler secret put META_PIXEL_ID # …every platform secret you need npx wrangler deploy
shell
curl -X POST https://<your-worker>/track \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "purchase",
"value": 49,
"currency": "USD",
"user": { "email": "a@b.com" },
"consent": { "adUserData": true, "adPersonalization": true }
}'
# Log the fan-out without sending:
curl -X POST "https://<your-worker>/track?dryRun=1" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"purchase","consent":{"adUserData":true,"adPersonalization":true}}'GET / is an unauthenticated health check. Platform secrets never travel in the request body.
Python example
python
import os, requests
resp = requests.post(
"https://<your-worker>/track",
headers={
"Authorization": f"Bearer {os.environ['RELAY_AUTH_TOKEN']}",
"Content-Type": "application/json",
},
json={
"name": "purchase",
"value": 49,
"currency": "USD",
"user": {"email": "a@b.com"},
"consent": {"adUserData": True, "adPersonalization": True},
},
timeout=15,
)
print(resp.json()) # { "results": [ { "platform": "meta", "ok": true }, … ] }Durable delivery
POST /track/async enqueues the event and returns 202 immediately. A queue consumer runs the same fan-out; Cloudflare retries failed messages. Requires queue bindings — see the worker README. If the queue binding is missing, /track/async returns 503 (it does not fall back to inline /track).
shell
# Enqueue and return 202 immediately (requires queue bindings — see worker/README.md)
curl -X POST https://<your-worker>/track/async \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"purchase","value":49,"currency":"USD","user":{"email":"a@b.com"},"consent":{"adUserData":true,"adPersonalization":true}}'Option B — CLI
Shell out from CI, cron, or any backend that can run a subprocess. Secrets come from the process environment.
shell
# From CI, a cron job, or any shell — no JS runtime in your app required npx adscapi platforms npx adscapi check npx adscapi verify npx adscapi test-event --event purchase --email you@example.com --dry-run npx adscapi offline --platform bing --file conversions.csv npx adscapi creatives upload --platform meta --image https://cdn.example.com/hero.jpg