Reject codes
Every reason a ping can end without a bid, every warning a bid can carry, every reason a bid did not become a call and every payout term — by number, with what to do about each.
After this page you can look up any number the RTB surface gave you, tell at a glance whether it is yours to fix or somebody else's, and write code that branches on the outcome rather than on a sentence.
When a ping gets no bid, the response carries a reject object: a numeric code, a short machine-readable reason and a description in words.
{
"ok": false,
"bidId": null,
"payout": 0,
"payoutCents": 0,
"reject": {
"code": 1006,
"reason": "outside_hours",
"description": "Outside hours of operation"
},
"auctionId": "AU-100483"
}A no-bid is a 200. Three refusals keep their own status so an HTTP client notices them — 429 for 1024, and 409 for 1025 and for a caller who already holds a live bid on the campaign — and the authentication refusals at the foot of this page are 401 and 403.
The campaign, the account and the lane
| Code | Reason | What it means | What to do |
|---|---|---|---|
1001 | campaign_disabled | That campaign is not live. | Nothing sent to it can be bought. Ask the buyer when it reopens. |
1002 | publisher_not_live | That publisher is not live. | The account itself is stopped. The buyer can say why and switch it back on. |
1015 | lane_inactive | You do not have an active lane on this campaign. | The lane has been removed or switched off. Ask for it to be re-opened before sending more traffic. |
1003 | no_capacity | No target had capacity for that call. | Nobody had room at that moment. Capacity changes minute to minute — keep pinging. |
1004 | caller_blocked | That caller is suppressed. | That number cannot be sold. Suppress it your side too. |
1005 | tag_filter | A bid rule rejected that call. | The tags on the ping did not pass the campaign's filters. Check the values you send against what the campaign asks for. |
1006 | outside_hours | Outside hours of operation. | The ping arrived outside the hours the campaign, or your lane on it, is open. Schedule your media, or ask for the hours. |
1008 | state_not_targeted | That state is not being bought. | Filter that state out of your own traffic, or ask for it to be added to the lane. |
1009 | duplicate_caller | That caller is inside the duplicate window. | They already reached the campaign recently and would not be paid again. De-duplicate before pinging. |
1010 | below_floor | The best bid was below the floor. | The best price offered for that caller was under the campaign's minimum. Nothing to fix; it changes call by call. |
1011 | no_bids | No target returned a bid. | Nobody wanted that caller. Keep pinging. |
1012 | margin_floor | The best bid does not clear the margin floor. | No price offered was high enough to pay you for the call. |
1013 | concurrency | Your concurrency limit is full. | Your lane is already carrying its maximum simultaneous calls. Wait for one to end, or ask for a higher limit. |
1014 | publisher_capped | Your cap for this campaign is filled. | A cap on your lane has been reached. It reopens when the window rolls over. |
1016 | workspace_inactive | That campaign's account is not active. | The buyer's own subscription has lapsed, so nothing on their campaigns can be bought. Nothing to fix your side — ask them when it is back. |
1017 | workspace_unfunded | That campaign's account cannot take calls right now. | The buyer's balance will not cover a call. It clears when they fund it; keep pinging, or ask them. |
1001 and 1002 are the numeric forms of two refusals that are answered at the door as 403 campaign_not_live and 403 publisher_not_live, before an auction exists. They are what the ping ledger and the publisher portal record for those requests.Too many requests
| Code | Reason | What it means | What to do |
|---|---|---|---|
1024 | rate_limited | Too many requests. | Answered 429 with a Retry-After header. Wait that long — pinging through a limit only uses up the next window. |
1025 | bid_in_flight | An identical request is being scored. | Answered 409. Wait for the first answer rather than sending the same request twice. A lock left behind by a crashed request clears itself after ten seconds. |
1026 | too_many_live_bids | Too many live bids for that caller. | Post or release one of the bids you already hold for that caller. The limit is per key. |
The caller
| Code | Reason | What it means | What to do |
|---|---|---|---|
1100 | caller_id_required | This campaign requires a caller ID. | Send callerId on every ping. whoami reports whether the campaign requires it. |
1101 | caller_id_invalid | That caller ID is not a usable number. | Ten digits, eleven digits starting with 1, or E.164 are all accepted. Anything else is refused. |
At post time
| Code | Reason | What it means | What to do |
|---|---|---|---|
1000 | no_capacity_at_post | The winning target filled before you posted. | The winner filled in the seconds between the ping and the post, and no runner-up could take the caller. Ping again for a fresh bid. |
1007 | caller_id_mismatch | The caller ID does not match the bid. | Post the same caller the bid was quoted for. Leaving callerId out counts as a mismatch when the campaign requires one. |
1018 | no_destination | That lane has no number or SIP address to send the caller to. | The bid would have been yours, but there is nowhere to transfer the caller. Ask for a number to be attached to your lane — the same condition warns as 250 when a claim does succeed. |
1040 | terms_changed | Those tags would have changed the price. | Send the tags on the ping, where the price is decided, not for the first time on the post. |
1040 is defined in the protocol and is not returned by any endpoint today: a post's tags are accepted and the call keeps the tags from the ping, because those are what the price was quoted on.The request itself
| Code | Reason | What it means | What to do |
|---|---|---|---|
3024 | missing_required_tags | Required tags were not supplied. | The names that were missing come back under details.missing. whoami lists what the campaign requires. |
3025 | malformed_request | The request could not be parsed. | Answered 400. The body is not valid JSON, or not the content type it claims to be. |
4005 | wrong_protocol | That key is not enabled for this protocol. | Answered 403. The key belongs to another surface. Ask for its protocol to be changed. |
Authentication
These are refused before an auction exists, so they carry no reject object — the body is { "ok": false, "error": "…", "message": "…" }, with code on the four signature failures. Each one is still a row in the ping ledger.
| Code | error | Status | What to do |
|---|---|---|---|
| — | missing_key | 401 | Send the key as Authorization: Bearer b3k_live_…. |
| — | invalid_key | 401 | The key is not recognised, or was revoked and its grace period is over. Ask for a new one. |
4000 | signature_missing | 401 | One of the three signature headers, or the v1 field, is absent. |
4001 | signature_invalid | 401 | Sign the exact bytes you send, with the current secret. A library that re-serialises after signing fails here. |
4002 | signature_stale | 401 | The timestamp is more than 300 seconds from the platform's clock. Check the sending server's time. |
4003 | nonce_replay | 401 | That nonce has been used. Mint a new one for every request, retries included. |
| — | ip_not_allowed | 403 | The request came from an address that is not on the key's allowlist. |
| — | compat_disabled | 403 | The single-step ping URL for that lane is switched off. |
| — | idempotency_key_required | 400 | Every post needs an Idempotency-Key header. |
code. The rest are identified by error alone, so match on that string. Full detail is in Keys and security.Warnings
A warning never changes the outcome. It exists so an integrator can see a problem before it becomes a support ticket. Warnings arrive as a warnings array of { code, description } and are present only when there is something to say.
| Code | What it means | What to do |
|---|---|---|
200 | A bid cannot be guaranteed without a caller ID. | Send callerId. Without it the platform cannot hold the bid against a person, and the post can be refused. |
205 | SIP delivery is preferred over the number. | Send sipOk: true and transfer to the sipAddress you are given. A SIP leg always reaches the platform; a number only does when it is one of the platform's own. |
220 | Test mode — real pricing, a destination that cannot be dialled. | The key is a test key. The auction ran and a slot is genuinely held, so release the bid rather than leaving it to expire. |
222 | Sandbox mode — synthetic pricing, a destination that cannot be dialled. | The key is a sandbox key. Nothing here reflects real demand. |
230 | A cached bid — your previous bid for this request has not expired. | You asked again for a caller you already hold a bid on and were given the same bid, not a second reservation. Post the one you have. |
240 | One or more targets exceeded the ping timeout and were excluded. | Nothing to do on your side. The price you were quoted is from the buyers who answered in time. |
250 | The bid was won, but this lane has no number or SIP address to send the caller to. | There is nowhere to transfer the caller. Ask for a number to be attached to the lane before sending traffic. |
Why a bid did not become a call
A bid that was made and then lost carries a loss code. It is on the bid in the ledger and is sent to external bidders on a loss notice. 0 is a win, which keeps "did this bid convert" a single comparison.
| Code | What it means | What to do |
|---|---|---|
0 | Won. The bid became the call. | — |
100 | The bid was below the campaign's floor. | Bid higher, or accept that this campaign is not for you. |
102 | Outbid. Another target offered more. | Nothing is wrong. Price is the lever. |
104 | Suppressed before the hold was taken. | Something about the caller disqualified them after bidding. |
1000 | The winner's capacity was gone by the time the caller was posted. | A race between the ping and the post. The runner-up takes the call where one has room. |
1001 | The hold expired before the caller was posted. | Post sooner. The expiry is on every bid. |
1002 | The caller hung up before delivery. | Release a bid you are not going to use, so the slot reopens at once. |
1003 | Nobody answered before the dial timed out. | The buyer's line did not pick up inside the campaign's dial timeout. |
1004 | The buyer declined the whisper. | The buyer heard the call's summary and refused it. |
1005 | The call failed on the SIP leg. | A carrier or endpoint failure. The call waterfall has the SIP result in words. |
1006 | A duplicate caller inside the dedupe window. | The same caller had already been sold recently. |
1007 | The caller ID did not match the bid. | The caller who arrived is not the one the bid was quoted for. |
1008 | The buyer was at their concurrency limit. | Their line was full when the call was offered. |
1009 | The call ended below the billable duration. | It connected and did not last long enough to count. |
100, 104, 1006 and 1009. A ledger row written by a newer build than this page still renders, so treat an unfamiliar number as informational rather than as an error.What a payout depends on
A bid carries a terms array. Those terms are frozen onto the bid when it is quoted and read back by settlement, so the conditions that decide the money are the ones you were quoted — not whatever the campaign says by the time the call ends.
"terms": [
{ "code": 101, "description": "Call must connect" },
{ "code": 100, "description": "Minimum connected duration 90 seconds", "seconds": 90 },
{ "code": 110, "description": "Duplicate callers are not paid within 86400 seconds", "seconds": 86400 }
]| Code | What it means | Carries |
|---|---|---|
101 | The call must connect. It is on every bid. | — |
100 | A minimum connected duration. | seconds |
102 | The call must be marked converted — a postback or a sale disposition is required. | — |
110 | Duplicate callers are not paid inside a window. | seconds |
Reading a refusal from the other side
The descriptions above are written for the publisher who receives them, which is why a handful are in the second person. A workspace reading its own ping ledger sees the same codes reworded — 1014 reads "The publisher's cap for this campaign was filled" — because "your" would point at the wrong party. The code is the same number either way.
Each refusal also carries an owner: whose move it is. It is the fastest way to triage a bad afternoon.
| Owner | Codes it covers | Means |
|---|---|---|
publisher | 1005, 1008, 1009, 1024, 1025, 1026, 1100, 1101, 1007, 3024, 3025, the signature codes | Something in the request, or on the sender's side, to change. |
network | 1001, 1002, 1006, 1013, 1014, 1015, 1016, 1017, 1018, 4005 | A rule the buyer set, or a state of their account. Ask them. |
demand | 1003, 1010, 1011, 1012, 1000 | Nobody wanted that caller, or nobody had room. It changes call by call. |
platform | Anything else | Ours. |
A worked example
Northwind Media send 400 pings on a Friday and win 90. Their ping summary ranks the refusals:
1008 state_not_targeted, 210 pings, ownerpublisher. They are sending states the lane does not buy. That is theirs to filter, and it is most of the gap.1006 outside_hours, 61 pings, ownernetwork. Their evening traffic arrives after the lane closes. They ask the buyer, who widens the hours.1011 no_bids, 33 pings, ownerdemand. Nobody wanted those callers. Nothing to fix.1024 rate_limited, 6 pings, ownerpublisher. A burst went over the minute limit. They honourRetry-Afterinstead of retrying immediately.
Two of the four are theirs, one is the buyer's and one is nobody's. The conversation that follows is about the two that can be changed.
