Warming up the decks…
Warming up the decks…
BlendPartner APIblendapp.aiBlend issues you three credentials. Two authenticate your backend on every call; the third signs the one request that moves money. All three arrive by email and none of them appear in this documentation.
| Credential | Type | Description |
|---|---|---|
| x-blend-key required | ck_live_… | Identifies your channel. Not a secret, it is safe to log and safe in a support ticket. |
| x-blend-secret required | cs_live_… | Authenticates your backend. Treat it like a database password: server-side only, never in an app binary, never in a log line. |
| signing key | csig_live_… | Signs order confirmations. Sent as x-blend-signature, computed per request, the key itself is never transmitted. |
Send the key and the secret as headers. There is no OAuth dance, no token to refresh and no expiry to handle.
curl https://api.blendapp.ai/api/v1/channel/events \
-H "x-blend-key: ck_live_xxxxxxxxxxxxxxxx" \
-H "x-blend-secret: cs_live_xxxxxxxxxxxxxxxx"| Status | Type | Description |
|---|---|---|
| 401 | MISSING_CREDENTIALS | One or both headers were absent. |
| 401 | INVALID_CREDENTIALS | The key is unknown, or the secret does not match it. Blend performs the same work either way, so this response cannot be timed to discover valid keys. |
| 403 | IP_NOT_ALLOWED | Your key has an IP allowlist and this request did not come from it. Send Blend the egress addresses of your servers. |
| 403 | SCOPE_DENIED | The key is valid but lacks the scope this endpoint needs. |
Keys carry scopes so a credential used for browsing cannot also spend. Most partners hold both.
| Scope | Type | Description |
|---|---|---|
| catalog.read | read | List events and read event detail. |
| orders.write | write | Mint buyer sessions, reserve orders, confirm payments. |
The confirm call is the only request that moves money, so it carries a signature in addition to your credentials. Sign the exact string below, the fields joined by full stops, the amount always to two decimal places.
import crypto from "node:crypto";
const payload = `${orderId}.${amount.toFixed(2)}.USD.${partnerReference}`;
const signature = crypto
.createHmac("sha256", process.env.BLEND_SIGNING_KEY)
.update(payload)
.digest("hex");42.5 must be signed as 42.50. A signature computed over the unformatted number will not match and the call is refused with 401 INVALID_SIGNATURE, the single most common integration mistake on this endpoint.
Tell Blend immediately. A signing key can be rotated on request and the previous key stops working the moment the new one is issued, you change one environment variable, with no release. A leaked secret is handled by issuing you a fresh key pair and disabling the old one.
Application binaries are downloadable and readable. Every call in this integration that requires the secret or the signing key is a server-side call by design, if you find yourself wanting one in the app, the flow you are reaching for has a backend equivalent.