POST /v1/sms/pre-send
The pre-send endpoint is the core compliance gate. It runs 6 checks in sequence before returning an allow/block decision — all in under 200ms.
Compliance Chain
Section titled “Compliance Chain”1. Quota check → Monthly limit reached?2. Quiet hours → Before 8 AM or after 9 PM local time?3. Frequency caps → Over 3 messages/day to this number?4. Revocation check → Consumer sent STOP?5. Double opt-in → Awaiting confirmation?6. Consent lookup → Valid consent on file?Request
Section titled “Request”POST https://sms.econsent.org/v1/sms/pre-sendAuthorization: Bearer ec_sms_YOUR_KEYContent-Type: application/json{ "phone": "+15551234567", "sending_entity": "Acme Insurance LLC", "sending_number": "+18005550100", "message_type": "marketing"}| Field | Type | Required | Description |
|---|---|---|---|
phone | string | Yes | Recipient phone (10-11 digits) |
sending_entity | string | Yes | Your business name |
sending_number | string | No | Your sending number |
message_type | string | Yes | marketing, transactional, mixed, or informational |
Response — Allowed
Section titled “Response — Allowed”{ "allowed": true, "decision_id": "dec_sms_abc123", "consent": { "consent_id": "cst_sms_xyz789", "captured_at": "2026-04-15T14:30:00Z", "type": "prior_express_written", "scope": ["marketing"], "evidence_url": "https://verify.econsent.org/c/cst_sms_xyz789" }, "compliance_notes": []}Response — Blocked
Section titled “Response — Blocked”{ "allowed": false, "reason": "quiet_hours", "decision_id": "dec_sms_abc124", "recipient_timezone": "America/New_York", "recipient_local_time": "21:45", "quiet_hours": { "start": "21:00", "end": "08:00" }, "next_allowed_at": "2026-04-18T08:00:00-04:00"}Block Reasons
Section titled “Block Reasons”| Reason | Description |
|---|---|
quiet_hours | Marketing message outside 8 AM - 9 PM local time |
frequency_cap | Over daily limit for this phone number |
consumer_revoked | Consumer sent STOP keyword |
pending_double_optin | Consent awaiting confirmation |
no_consent_on_file | No valid consent found |
quota_exceeded | Monthly API quota reached |