§08 · API Webhooks Signed deliveries for launches, trades, graduations, burns, buybacks, payouts and claims.
Webhooks need an API key (a free one works). Register with POST /v1/webhooks; the response has the signing secret, shown once. A free key can hold 5 webhooks, a partner key 50.
curl Copy
curl -X POST "https://api.justi.fun/v1/webhooks" \
-H "Authorization: Bearer $JUSTI_API_KEY" -H "Content-Type: application/json" \
-d '{"url":"https://example.com/hooks/justi","events":["launch.created","trade","coin.graduated"],"mints":null}' # Events# Verify signaturesEach delivery is POST with JSON { id, type, createdAt, data } and headers Justi-Event, Justi-Delivery and Justi-Signature: t=<unix>,v1=<hex>, where v1 = HMAC-SHA256(secret, "<t>.<raw body>"). Check it against the raw bytes you received, before parsing, and refuse timestamps more than 5 minutes off.
TypeScript (SDK) Node (no SDK) Python
Copy import { verifyWebhook } from "@justifun/sdk" ;
// Express: keep the raw body for this route
app.post("/hooks/justi" , express.raw({ type : "application/json" }), async (req, res) => {
const ok = await verifyWebhook(req.body, req.get("Justi-Signature" ), process.env.JUSTI_WEBHOOK_SECRET!);
if (!ok) return res.status(400 ).end();
const event = JSON.parse(req.body.toString("utf8" )); // { id, type, createdAt, data }
// dedupe on event.id, then handle event.type
res.status(200 ).end();
});# Retries and disablingAny 2xx is success. Redirects are not followed. Answer within a few seconds and do slow work after. Up to 8 attempts, waiting 30 s x 3^(n-1) capped at 6 hours, with 20% jitter: about 9 hours in all. After 5 failures in a row a webhook gets one probe delivery per second until it answers; the rest wait. After 25+ failed attempts in a row over at least an hour it is disabled and its queue is cancelled. PATCH { enabled: true } turns it back on. Order is not guaranteed. Dedupe on id. History is never replayed into a new webhook. The delivery log (GET /v1/webhooks/{id}/deliveries) shows status, attempts, last status code, error, duration and payload. # PayloadsCaptured from real deliveries:
trade Copy
{"id" :"evt_24" ,"type" :"trade" ,"createdAt" :1793110075 ,"data" :{"mint" :"AxqRtyYz9pNyqZZfvFwjvhJbnQfNaHMofZH43Mhb23Da" ,"ticker" :"" ,"venue" :"curve" ,"side" :"buy" ,"wallet" :"Hkm9m53BVZsV3SRf23zzq6BVEpcsfz2M6Ucsa837Nzk7" ,"solLamports" :"8212500000" ,"tokenAmount" :"22249603316556" ,"priceSol" :4. 463611817123742e-7 ,"marketCapSol" :446.3611817123742 ,"signature" :"5bqKP1FxfcYeQgRf5VH6dQ5QaSdvvsJMy5sJ1Uew5QY1d8twY5ZTzjpvY9bUPBbyf6eRY4LMLzFX6ZXJn91WSn7g" ,"ix" :"4" ,"slot" :462098540 ,"ts" :1793110057 ,"inWindow" :true }}coin.graduated Copy
{"id" :"evt_23" ,"type" :"coin.graduated" ,"createdAt" :1793110030 ,"data" :{"mint" :"8Qs4Jb16QKuZyb13dKAbjw3DpbDM7KqUmqeajjaa3bMk" ,"ticker" :"" ,"name" :"" ,"curvePool" :"DvyctJAp1oJ4gsQMgZ9tMbZzYrPUGf8dTk5rk3RyqwrH" ,"dammPool" :"7JSjaVcgQasuSRbjs1rY7T4zBxnnxXWQ4BmKETn7wuqV" ,"migrationSignature" :"3ZQ72yceM8kNNLWvwk9J6ZZ3yGt1ooXj9PS8qdW8m5A3Djw3nwS2nruDPnmKSDbwkCAG8H1WtXHiVVzNV9opx3sc" ,"ts" :1793057896 }}launch.created (fields) Copy
{"id" :"evt_..." ,"type" :"launch.created" ,"createdAt" :0 ,"data" :{"mint" :"...JUST" ,"name" :"..." ,"ticker" :"..." ,"description" :"..." ,"image" :"https://api.justi.fun/v1/image/<launchId>" ,"metadataUri" :"https://api.justi.fun/v1/meta/<launchId>" ,"creator" :"<wallet>" ,"curvePool" :"..." ,"config" :"..." ,"tier" :"split-50" ,"activationTs" :0 ,"signature" :"<create tx>" ,"devBuyTokens" :"3680660059553" ,"partner" :null }}Note The other payloads: buyback {id, mint, kind, lamports, tokensBought, route, swapSignature, ts}, burn {id, mint, kind, lamports, tokensBurned, swapSignature, burnSignature, ts}, payout {id, wallet, lamports, signature, ts}, creator.claim {mint, wallet, lamports, signature, ts}. The SDK exports types for all of them.
# Reference# Register a webhook (the secret is shown once)POST /v1/webhooks
Key required Rate class manage Body 8kb createWebhook
Deliveries are POSTs of {id,type,createdAt,data} with headers Justi-Event, Justi-Delivery and Justi-Signature: t=<unix>,v1=<hex HMAC-SHA256(secret, "<t>.<raw body>")>. Any 2xx is success. Retries: 8 attempts, 30s x 3^(n-1) (cap 6h, +-20% jitter). 25 failures in a row disable the webhook. trade events can be limited to mints.
Body Response WebhookCreated Errors 400 bad_request, invalid_params, invalid_json 401 unauthorized 409 conflict 413 payload_too_large 429 rate_limited 500 internal
curl -X POST "https://api.justi.fun/v1/webhooks" \
-H "Authorization: Bearer $JUSTI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com/hooks/justi","events":["launch.created","trade"],"description":"hold the line."}' # Webhooks of this API keyGET /v1/webhooks
Key required Rate class manage listWebhooks
Response object Errors 400 invalid_params 401 unauthorized 429 rate_limited 500 internal
curl "https://api.justi.fun/v1/webhooks" \
-H "Authorization: Bearer $JUSTI_API_KEY" # One webhookGET /v1/webhooks/{id}
Key required Rate class manage getWebhook
Parameters Response Webhook Errors 400 invalid_params 401 unauthorized 404 not_found 429 rate_limited 500 internal
curl "https://api.justi.fun/v1/webhooks/<id>" \
-H "Authorization: Bearer $JUSTI_API_KEY" # Change a webhook; enabled=true re-enables one that was disabledPATCH /v1/webhooks/{id}
Key required Rate class manage Body 8kb updateWebhook
Parameters Body Response Webhook Errors 400 bad_request, invalid_params, invalid_json 401 unauthorized 404 not_found 413 payload_too_large 429 rate_limited 500 internal
curl -X PATCH "https://api.justi.fun/v1/webhooks/<id>" \
-H "Authorization: Bearer $JUSTI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com/hooks/justi","events":["launch.created","trade"],"description":"hold the line."}' # Delete a webhook and its delivery logDELETE /v1/webhooks/{id}
Key required Rate class manage deleteWebhook
Parameters Response object Errors 400 invalid_params 401 unauthorized 404 not_found 429 rate_limited 500 internal
curl -X DELETE "https://api.justi.fun/v1/webhooks/<id>" \
-H "Authorization: Bearer $JUSTI_API_KEY" # Delivery log, newest firstGET /v1/webhooks/{id}/deliveries
Key required Rate class manage listWebhookDeliveries
Parameters Response object Errors 400 invalid_params 401 unauthorized 404 not_found 429 rate_limited 500 internal
curl "https://api.justi.fun/v1/webhooks/<id>/deliveries?limit=20" \
-H "Authorization: Bearer $JUSTI_API_KEY" # Send one signed webhook.test delivery nowPOST /v1/webhooks/{id}/test
Key required Rate class manage testWebhook
Parameters Response object Errors 400 invalid_params 401 unauthorized 404 not_found 429 rate_limited 500 internal
curl -X POST "https://api.justi.fun/v1/webhooks/<id>/test" \
-H "Authorization: Bearer $JUSTI_API_KEY" Previous Data API Next Streams