Skip to content

API reference/phone

Reported SMS outcomes

GET/api/v1/phone/feedback/summary

authentication
Secret API key as a bearer token
billing
Free.

The last 90 days of outcomes you reported: totals per outcome, the failed deliveries split by failure class in undelivered_by_class, how many distinct numbers they cover, verified_share (of the distinct numbers you reported delivered or verified, the share you reported verified), and the ten blocks (region plus the first six digits of the national number) with the most failed deliveries about the number, with their delivered, abused and verified counts and their own verified_share alongside. A bad list or a wholesaler's range shows up here first, and so does pumped traffic: delivered, never verified, in a block whose share sits far under yours. Your own sending problems — a lapsed campaign registration, a carrier filter — show under sender_side instead of in the blocks.

Example request

curl https://spaw.co/api/v1/phone/feedback/summary \
  -H "Authorization: Bearer sk_live_…"
const response = await fetch('https://spaw.co/api/v1/phone/feedback/summary', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer sk_live_…',
  },
});
const result = await response.json();
import requests

response = requests.get(
    'https://spaw.co/api/v1/phone/feedback/summary',
    headers={'Authorization': 'Bearer sk_live_…'},
)
result = response.json()
$ch = curl_init('https://spaw.co/api/v1/phone/feedback/summary');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ['Authorization: Bearer sk_live_…'],
]);
$result = json_decode(curl_exec($ch), true);
from spaw import Client

client = Client('sk_live_…')
result = client.phone_feedback_summary()
import Spaw from 'spaw';

const spaw = new Spaw({ apiKey: 'sk_live_…' });
const result = await spaw.phoneFeedbackSummary();
use Spaw\Client;

$spaw = new Client('sk_live_…');
$result = $spaw->phoneFeedbackSummary();

This endpoint has no console on its page. It answers with records from your own account, often by an id only you have, rather than about a value you can type here. The dashboard lists the same rows.

Responses

200The summary.

{
    "success": true,
    "data": {
        "window_days": 90,
        "total": 3120,
        "numbers": 2870,
        "outcomes": {
            "delivered": 2988,
            "undelivered": 119,
            "abused": 11,
            "verified": 2410,
            "opted_out": 2
        },
        "verified_share": 0.812,
        "undelivered_by_class": {
            "permanent": 9,
            "transient": 64,
            "not_sms_capable": 3,
            "sender_side": 38,
            "unclassified": 5
        },
        "top_undelivered_blocks": [
            {
                "country": "US",
                "block": "201201",
                "undelivered": 38,
                "delivered": 2,
                "abused": 4,
                "verified": 0,
                "verified_share": 0
            },
            {
                "country": "GB",
                "block": "770090",
                "undelivered": 12,
                "delivered": 0,
                "abused": 0,
                "verified": 0,
                "verified_share": null
            }
        ]
    }
}

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"
    }
}

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.

markdown version·openapi.json