- authentication
- Secret API key as a bearer token
- billing
- Free.
Tells Spaw what happened after you sent an SMS to a number: delivered, undelivered (the carrier reported it could not be delivered), or abused (the code was used by someone who was not the recipient, or the number was involved in fraud). Your own reports feed your own later lookups of that number as risk signals with the dataset delivery-feedback: a number whose latest report within 90 days is undelivered scores reported_undelivered (+50), a number with any abuse report within 90 days scores reported_abuse (+60), and a delivery reported after a failure cancels that failure. No other account ever sees your reports.
Numbers are normalised like a lookup; national notation needs a country on the item or on the request. Items whose number does not parse as a valid subscriber number are skipped and counted, not rejected. Feedback is free and never logged as a lookup. Outcomes are kept for 180 days.
Request body
| field | type | description |
|---|---|---|
| itemsrequired | object[] | 1 to 1,000 outcomes per request. |
| items[].phonerequired | string | The number, in any common notation. At most 32 characters. |
| items[].outcomerequired | string | One of: delivered, undelivered, abused. |
| items[].country | string | null | An ISO 3166-1 alpha-2 region for a number written without a calling code; overrides the request-level country. |
| items[].occurred_at | string | null | When it happened. Defaults to now. |
| country | string | null | An ISO 3166-1 alpha-2 region applied to items that do not name their own, for numbers written without a calling code. |
Example request
curl -X POST https://spaw.co/api/v1/phone/feedback \
-H "Authorization: Bearer sk_live_…" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"phone": "+44 7911 012345",
"outcome": "undelivered"
},
{
"phone": "(415) 555-0142",
"country": "US",
"outcome": "delivered",
"occurred_at": "2026-09-05T09:00:00Z"
}
]
}'Responses
202The outcomes were recorded.
{
"success": true,
"data": {
"recorded": 2,
"skipped": 0
}
}401The key is missing, malformed, or revoked.
{
"success": false,
"error": {
"code": "UNAUTHENTICATED",
"message": "Provide a valid API key as a bearer token.",
"request_id": "req_01m1kgdm4xngzmbmff68g94w0c"
}
}422The request body could not be validated; `error.errors` lists the fields.
{
"success": false,
"error": {
"code": "VALIDATION_FAILED",
"message": "The email field is required.",
"errors": {
"email": [
"The email field is required."
]
},
"request_id": "req_01m1kgdm4xngzmbmff68g94w0c"
}
}429Over 5 requests per second for the key. Retry after the limit resets.
{
"success": false,
"error": {
"code": "RATE_LIMITED",
"message": "Too many requests. Retry after the limit resets.",
"request_id": "req_01m1kgdm4xngzmbmff68g94w0c"
}
}Error codes
Failures answer { success: false, error: { code, message, request_id } }. Each code has its own page.