curl --request POST \
--url https://api.1-funnel.org/v1/businesses/{businessId}/sms/messages \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: <idempotency-key>' \
--data '
{
"from": "1FUNNEL",
"to": "+2348012345678",
"classification": "transactional"
}
'{
"id": "018f3c4e-7b2a-7c3d-8e9f-aaaaaaaaaaaa",
"business_id": "018f3c4e-7b2a-7c3d-8e9f-0123456789ab",
"from": "1FUNNEL",
"to": "+2348012345678",
"classification": "transactional",
"message": "Your order ORD-1001 is confirmed.",
"status": "queued",
"status_reason": null,
"template": null,
"accepted_at": "2026-10-13T09:00:00.000Z",
"submitted_at": null,
"delivered_at": null,
"failed_at": null
}Submit an individual SMS
Durably accept an individual SMS for asynchronous processing (ADR-018 SMS-01).
202 is not delivery confirmation. Requires Idempotency-Key (DEC-SMS-I01).
curl --request POST \
--url https://api.1-funnel.org/v1/businesses/{businessId}/sms/messages \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: <idempotency-key>' \
--data '
{
"from": "1FUNNEL",
"to": "+2348012345678",
"classification": "transactional"
}
'{
"id": "018f3c4e-7b2a-7c3d-8e9f-aaaaaaaaaaaa",
"business_id": "018f3c4e-7b2a-7c3d-8e9f-0123456789ab",
"from": "1FUNNEL",
"to": "+2348012345678",
"classification": "transactional",
"message": "Your order ORD-1001 is confirmed.",
"status": "queued",
"status_reason": null,
"template": null,
"accepted_at": "2026-10-13T09:00:00.000Z",
"submitted_at": null,
"delivered_at": null,
"failed_at": null
}Authorizations
OAuth 2.0 Client Credentials for the External Integration API (ADR-015, ADR-023).
Client authentication: HTTP Basic (client_secret_basic).
Access-token audience: 1funnel-external-api.
The tokenUrl below is the production target. Sandbox uses a different
host. OpenAPI cannot bind tokenUrl to the selected servers entry; see
x-1funnel-oauth on the root document and the authentication guide when published.
Coarse OAuth scopes (if any) are token-level vocabulary (ADR-013 IA-06). They
are not the ADR-022 resource permission catalogue. Resource permissions
are enforced after token validation via application-to-business grants
(ADR-016) and are documented per operation with x-required-permissions.
These URLs are architecture targets. They are not claimed to be deployed or generally available.
Headers
Required for this designated state-changing operation (STD-API-01 D09, ADR-017 SECOP-05/06, DEC-SMS-I01 shared external idempotency model).
Scope: (application_id, business_id, operation, idempotency_key).
Permanent uniqueness within scope; seven-day response replay for equivalent
payloads; 409 idempotency_conflict on payload mismatch; reuse after
replay expiry must never create a new operation. See the optional
Idempotency-Key component description for concurrent and
failed-before-acceptance rules.
1 - 256"idem_01HZX3K9EXAMPLE"
Request correlation identifier (STD-API-01 D12). Clients may supply a value
of 1–128 characters matching A-Za-z0-9._-. Missing or invalid values are
replaced by a server-generated identifier. Distinct from W3C traceparent,
resource ids, Idempotency-Key, and webhook event ids.
1 - 128^[A-Za-z0-9._-]+$"req_01HZX3K9EXAMPLE"
Path Parameters
Business resource selector in /v1/businesses/{businessId}/… (ADR-006).
UUIDv7-compatible opaque identifier. {businessId} is not authorization
proof. The resource server must independently verify an active
application-to-business grant, required permission, and ownership (ADR-016,
ADR-022).
UUID with version nibble 7 (UUIDv7). STD-API-01 prefers UUIDv7 for new
platform-generated external resource identifiers. Clients must still treat
the value as opaque. Not every path parameter is guaranteed to be v7 solely
because it is a UUID; use this schema where the contract asserts UUIDv7.
^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-7[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$"018f3c4e-7b2a-7c3d-8e9f-0123456789ab"
Body
Individual SMS submission (ADR-018 SMS-01 / SMS-09, DEC-SMS-N01 / T02).
Provide exactly one of free-text message or template_id. Do not supply
both. Clients must not supply authoritative segmentation or billing values.
Template submissions resolve and pin the current active revision at durable
acceptance; client-selected historical revisions are rejected.
Authorized sender identity. Backend validates authorization.
Invalid sender formatting → validation_failed. Unauthorized sender →
sender_not_authorized (403).
1 - 20"1FUNNEL"
Recipient MSISDN in E.164 format (+ followed by country code and subscriber
number). Leading + required.
9 - 16^\+[1-9]\d{7,14}$"+2348012345678"
Public message classification (lowercase snake_case). Transactional vs promotional distinction for compliance and routing policy.
transactional, promotional "transactional"
Unicode direct message content (DEC-SMS-N01). Required when template_id
is omitted. Segmentation is determined by the backend.
1 - 4096Business-owned template. Active revision resolved and pinned at acceptance
(DEC-SMS-T02). Archived or inactive templates → template_not_active.
^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-7[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$"018f3c4e-7b2a-7c3d-8e9f-0123456789ab"
Per-recipient or per-send template variables. Keys must match placeholders defined by the referenced template revision. Values are strings. Live OTP codes must not be supplied as template variables for the managed OTP product (ADR-008 / ADR-018 SMS-09).
Show child attributes
Show child attributes
{
"first_name": "Ada",
"order_id": "ORD-1001"
}
Response
Durably accepted for asynchronous processing
Individual SMS resource. Acceptance is not delivery confirmation. Status is the merchant-visible display projection (ADR-018 SMS-12).
UUID with version nibble 7 (UUIDv7). STD-API-01 prefers UUIDv7 for new
platform-generated external resource identifiers. Clients must still treat
the value as opaque. Not every path parameter is guaranteed to be v7 solely
because it is a UUID; use this schema where the contract asserts UUIDv7.
^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-7[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$"018f3c4e-7b2a-7c3d-8e9f-0123456789ab"
UUID with version nibble 7 (UUIDv7). STD-API-01 prefers UUIDv7 for new
platform-generated external resource identifiers. Clients must still treat
the value as opaque. Not every path parameter is guaranteed to be v7 solely
because it is a UUID; use this schema where the contract asserts UUIDv7.
^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-7[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$"018f3c4e-7b2a-7c3d-8e9f-0123456789ab"
Authorized sender identity for the business (from). The backend validates
that the application/business may use this sender. Arbitrary sender IDs are
not permitted. Public sender-ID management resources remain future
(ADR-018 SMS-19 / target architecture).
1 - 20"1FUNNEL"
Recipient MSISDN in E.164 format (+ followed by country code and subscriber
number). Leading + required.
9 - 16^\+[1-9]\d{7,14}$"+2348012345678"
Public message classification (lowercase snake_case). Transactional vs promotional distinction for compliance and routing policy.
transactional, promotional "transactional"
Merchant-visible individual message status (ADR-018 SMS-12). Display projection — not bulk processing status and not raw provider codes.
queued, sent, delivered, failed "delivered"
Durable acceptance timestamp (not provider submission or delivery).
"2026-10-13T09:00:00.000Z"
Effective message content after any template rendering at acceptance.
Optional finer failure or state detail. Not a provider-native code.
Revision pinned at durable acceptance when template-based.
Show child attributes
Show child attributes
{
"template_id": "018f3c4e-7b2a-7c3d-8e9f-0123456789ab",
"revision_id": "018f3c4e-7b2a-7c3d-8e9f-0123456789cd"
}
Provider submission timestamp when known.
"2026-10-13T09:00:00.000Z"
Delivery outcome timestamp when known.
"2026-10-13T09:00:00.000Z"
RFC 3339 date-time. Response timestamps are UTC with a Z offset
(STD-API-01 D06). Client-supplied timestamps must include an explicit offset;
local times without an offset are rejected.
"2026-10-13T09:00:00.000Z"