Publisher integration guide
AffsSpace External RTB
Send a bid request, evaluate the response, and route an accepted caller to the returned destination. The contract works with Ringba and any server-side call-routing platform that supports HTTPS and JSON.
Quick start
- 01
Get access
Receive an API key and Program ID from AffsSpace.
- 02
Send a bid
POST the caller ZIP and original caller ID to the Program endpoint.
- 03
Check accepted
Read the accepted field; HTTP 200 alone is not an accepted bid.
- 04
Route the caller
For accepted bids, route the same caller to destination.
API request
Each Program has a unique ID supplied by AffsSpace. Put it in the URL; do not send it again in the JSON body.
Endpoint
POST https://rtb.affs.space/api/v1/rtb/programs/{programId}/bidExample for Program 12018: https://rtb.affs.space/api/v1/rtb/programs/12018/bid
Authentication and headers
- API key
- X-API-Key: <YOUR_API_KEY>
- Content-Type
- application/json
- Idempotency-Key · optional, recommended
- Use 16–128 visible ASCII characters. Reuse the key only when safely retrying the exact same request.
Store API keys only in your server or call-routing platform. Never embed them in browser JavaScript.
{
"zip_code": "90710",
"caller_id": "+12025550123"
}zip_code must be a five-digit US ZIP Code.
caller_idis the caller's US phone number / ANI. Ten digits or a leading US country code are accepted, with common punctuation.
curl -X POST \
"https://rtb.affs.space/api/v1/rtb/programs/12018/bid" \
-H "X-API-Key: <YOUR_API_KEY>" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: request-12345-abc" \
-d '{
"zip_code": "90710",
"caller_id": "+12025550123"
}'API response
A valid request may return HTTP 200 with accepted=false. Always evaluate accepted before routing.
{
"accepted": true,
"bidId": "AFB_SAMPLE_BID_IDENTIFIER",
"bidAmount": 42.75,
"billableDuration": 100,
"destination": "+13105550123"
}- bidAmount
- Publisher-facing bid amount in USD.
- billableDuration
- Final duration requirement for this accepted bid, in seconds.
- destination
- Exact AffsSpace ingress to which the accepted physical caller must be routed.
- bidId
- AffsSpace identifier for support.
{
"accepted": false,
"rejectReason": "program_unavailable",
"retryable": false
}When accepted is false, do not route the call to an AffsSpace destination from that request.
rejectReason identifies the category and retryable indicates whether retrying is reasonable.
HTTP behavior
HTTP 200 carries the normal auction result, including a valid no-bid with accepted=false. HTTP 400 identifies an invalid request, HTTP 401 an invalid credential, HTTP 429 a bounded rate limit, and HTTP 503 a temporary infrastructure condition. Follow retryable and any Retry-After header; never infer acceptance from the HTTP status alone.
| Reason | Meaning |
|---|---|
| unauthorized | The API key is missing, malformed, or not accepted. |
| invalid_request | The JSON body or one of its fields is not accepted. |
| invalid_zip_code | zip_code is not a five-digit US ZIP Code. |
| invalid_caller_id | caller_id is not an accepted US phone number. |
| invalid_idempotency_key | Idempotency-Key does not satisfy the documented format. |
| publisher_inactive | The Publisher's External RTB profile is currently inactive. |
| publisher_disabled | The Publisher is currently paused. |
| program_inactive | The Program is currently paused. |
| publisher_program_inactive | The Publisher is not active for this Program. |
| program_unavailable | The Program cannot accept this request right now. |
| enrollment_not_ready | The Publisher enrollment is not ready to accept bids. |
| idempotency_conflict | The Idempotency-Key was already used with a different request payload. |
| idempotency_attempt_complete | That idempotent request already reached a terminal call state. |
| request_in_progress | The exact request is already being processed; retry as directed. |
| caller_attempt_in_progress | A request for this caller is already active; retry as directed. |
| conflicting_zip | An active request for this caller used a different ZIP Code and was not replaced. |
| active_offer_conflict | An existing offer prevents a second Buyer auction for this caller. |
| no_coverage | No bid is available for the submitted request. |
| buyer_duplicate_ping | The Buyer already received this bid request and did not return a new offer. |
| buyer_rate_limited | Buyer capacity is temporarily rate limited; follow retry guidance. |
| buyer_invalid_response | No usable Buyer response was available for this request. |
| margin_not_allowed | No Publisher-facing bid remained after the configured payout policy. |
| rate_limited | Request volume is temporarily limited; follow retry guidance. |
| temporarily_unavailable | A temporary service condition prevented a bid. |
Ringba setup
Create a Ring Tree Target in Advanced mode. Ringba UI labels and ZIP-capture tags can vary by account configuration; use your existing ZIP and original-ANI variables.
Request settings
- Method
- POST
- URL
- https://rtb.affs.space/api/v1/rtb/programs/{programId}/bid
- Content type
- application/json
- HTTP header key
- X-API-Key
- HTTP header value
- <YOUR_API_KEY>
- Body
- zip_code: <Ringba ZIP variable>
caller_id: <Ringba original Caller ID / ANI variable>
Response parsing · JPath
Enable Dynamic Number/SIP on the Ring Tree Target, then add these root-based expressions in Advanced mode. Use Ringba's Test Request to select and verify each response property in your account.
- Acceptance
- x.accepted
- Bid Amount
- x.bidAmount
- Required Duration
- x.billableDuration
- Destination
- x.destination
For Call Acceptance, compare the value extracted by x.accepted with true. A false value is a no-bid even though AffsSpace correctly returns HTTP 200. Map x.bidAmount to Dynamic Bid Parsing, x.billableDuration to Dynamic Duration Parsing, and x.destination to Dynamic Number/SIP Parsing.
destination and preserve the caller ID / ANI used in the bid request. Configure Ringba to use billableDurationfor that accepted bid's duration qualification and conversion tracking.Other platforms / custom integration
1. POST the Program endpoint.
2. Check accepted.
3. Read bid and duration, then route to destination or treat it as no bid.
response = POST(...)
if response.accepted:
bid = response.bidAmount
requiredDuration = response.billableDuration
routeCall(response.destination)
else:
noBid()Testing checklist
- ✓ Use a valid Program ID and API credential supplied by AffsSpace.
- ✓ Use a controlled caller ID and valid five-digit ZIP Code.
- ✓ Verify acceptance, bid, duration, and destination independently.
- ✓ Confirm accepted=false never routes to an AffsSpace destination.
- ✓ Place a controlled test call and preserve the original caller ANI.
- ✓ Verify the returned duration is used for qualification tracking.