API reference
Full list of REST endpoints by resource
All public endpoints relative to https://ecowave-api.builds.et/api/v1. Requests are scoped to the API key's organization.
API credentials
Manage organization API keys from an authenticated console session.
/api-keysList keys, environments, scopes, usage, and expiry.
owner/admin sessionRequest Body & Response Schemas
{
"data": [
{
"id": "key_12345",
"organizationId": "org_abc",
"name": "Production Service",
"prefix": "ew_live",
"publicId": "abc123xyz890",
"environment": "live",
"permissions": ["messages:send", "messages:read"],
"createdAt": "2026-08-01T12:00:00.000Z",
"lastUsedAt": "2026-08-09T10:00:00.000Z"
}
]
}/api-keysCreate a test or live key. The full secret is returned once.
owner/admin sessionRequest Body & Response Schemas
{
"organizationId": "org_abc",
"name": "Backend Integration Key",
"environment": "live",
"permissions": ["messages:send", "messages:read", "webhooks:read"]
}{
"id": "key_12345",
"name": "Backend Integration Key",
"environment": "live",
"key": "ew_live_abc123xyz890_SECRET_HASH_HERE",
"permissions": ["messages:send", "messages:read", "webhooks:read"],
"createdAt": "2026-08-09T10:00:00.000Z"
}/api-keys/{keyId}Update name, metadata, expiration, or permissions.
owner/admin sessionRequest Body & Response Schemas
{
"organizationId": "org_abc",
"name": "Updated Service Key",
"permissions": ["messages:send", "messages:read", "contacts:read"]
}{
"id": "key_12345",
"name": "Updated Service Key",
"permissions": ["messages:send", "messages:read", "contacts:read"],
"updatedAt": "2026-08-09T10:05:00.000Z"
}/api-keys/{keyId}Revoke a key immediately.
owner/admin sessionRequest Body & Response Schemas
HTTP 204 No ContentSecurity codes
Generate, deliver, and verify one-time codes for login, two-factor authentication, transactions, and custom flows.
/security-codes/sendGenerate and send a code by SMS. Supports configurable format, lifetime, attempts, templates, metadata, and Idempotency-Key.
security-codes:sendRequest Body & Response Schemas
{
"to": "+251911234567",
"channel": "sms",
"purpose": "two_factor",
"from": "EcoWave",
"code": { "type": "numeric", "length": 6 },
"ttlSeconds": 300,
"maxAttempts": 5,
"template": "Your {{purpose}} code is {{code}}. It expires in {{expiresInMinutes}} minutes.",
"metadata": { "userId": "user_123" }
}{
"verificationId": "7f8d9e1a-4b2c-4d5e-9f01-234567890abc",
"messageId": "3a2d14af-76cf-4b65-b5e0-b81e96bd4412",
"channel": "sms",
"purpose": "two_factor",
"status": "pending",
"expiresAt": "2026-08-19T12:05:00.000Z",
"expiresInSeconds": 300,
"createdAt": "2026-08-19T12:00:00.000Z"
}/security-codes/verifyVerify a submitted code. A code can only succeed once and is locked after its configured attempt limit.
security-codes:verifyRequest Body & Response Schemas
{
"verificationId": "7f8d9e1a-4b2c-4d5e-9f01-234567890abc",
"code": "482913"
}{
"valid": true,
"status": "verified",
"verificationId": "7f8d9e1a-4b2c-4d5e-9f01-234567890abc",
"purpose": "two_factor",
"verifiedAt": "2026-08-19T12:02:00.000Z",
"metadata": { "userId": "user_123" }
}Sender IDs
Request and track branded sender approval.
/sender-idsList requested, approved, and rejected sender IDs.
sender-ids:readRequest Body & Response Schemas
{
"data": [
{
"id": "snd_123",
"value": "EcoWave",
"status": "approved",
"useCase": "Transactional OTPs and alerts",
"createdAt": "2026-08-01T00:00:00.000Z"
}
]
}/sender-idsSubmit a sender ID with use case and sample content.
sender-ids:writeRequest Body & Response Schemas
{
"value": "MyBrand",
"useCase": "Order notifications and verification codes",
"sampleContent": "Your code for MyBrand is 123456."
}{
"id": "snd_456",
"value": "MyBrand",
"status": "pending",
"useCase": "Order notifications and verification codes",
"createdAt": "2026-08-09T10:00:00.000Z"
}Messages
Send transactional SMS and inspect delivery state.
/messagesEnqueue one SMS. Supports to, text, from, metadata, webhook, and Idempotency-Key.
messages:sendRequest Body & Response Schemas
{
"to": "+251911234567",
"text": "Your verification code is 482913.",
"from": "EcoWave",
"metadata": { "userId": "user_123" },
"webhook": {
"url": "https://example.com/webhooks/ecowave",
"secret": "my-secret-key-16-plus-chars"
}
}{
"id": "7f8d9e1a-4b2c-4d5e-9f01-234567890abc",
"organizationId": "org_abc",
"teamId": "org_abc",
"from": "EcoWave",
"senderId": "EcoWave",
"to": "+251911234567",
"recipient": "+251911234567",
"text": "Your verification code is 482913.",
"content": "Your verification code is 482913.",
"status": "queued",
"segments": 1,
"provider": "kannel",
"providerMessageId": null,
"errorCode": null,
"errorMessage": null,
"metadata": { "userId": "user_123" },
"environment": "live",
"statusWebhookUrl": "https://example.com/webhooks/ecowave",
"createdAt": "2026-08-09T10:00:00.000Z",
"acceptedAt": null,
"sentAt": null,
"deliveredAt": null,
"failedAt": null
}/messagesList recent messages. Returns data and nextCursor. Limit 1–100.
messages:readRequest Body & Response Schemas
{
"data": [
{
"id": "7f8d9e1a-4b2c-4d5e-9f01-234567890abc",
"from": "EcoWave",
"to": "+251911234567",
"text": "Your verification code is 482913.",
"status": "delivered",
"segments": 1,
"deliveredAt": "2026-08-09T10:00:05.000Z"
}
],
"nextCursor": null
}/messages/{messageId}Get content, segments, provider IDs, errors, and timestamps.
messages:readRequest Body & Response Schemas
{
"id": "7f8d9e1a-4b2c-4d5e-9f01-234567890abc",
"from": "EcoWave",
"to": "+251911234567",
"text": "Your verification code is 482913.",
"status": "delivered",
"segments": 1,
"createdAt": "2026-08-09T10:00:00.000Z",
"acceptedAt": "2026-08-09T10:00:01.000Z",
"sentAt": "2026-08-09T10:00:02.000Z",
"deliveredAt": "2026-08-09T10:00:05.000Z"
}Inbound SMS & keywords
Read MO messages and configure keyword auto-replies.
/inbound/messagesList inbound messages by processing state.
inbound:readRequest Body & Response Schemas
{
"data": [
{
"id": "inb_123",
"from": "+251911234567",
"to": "EcoWave",
"text": "START",
"status": "processed",
"receivedAt": "2026-08-09T10:00:00.000Z"
}
]
}/inbound/messages/{messageId}/redriveRequeue a failed inbound message.
inbound:writeRequest Body & Response Schemas
{ "id": "inb_123", "status": "received" }/inbound/keywordsList keyword rules.
inbound:readRequest Body & Response Schemas
{
"data": [
{
"id": "kw_123",
"keyword": "START",
"matchType": "exact",
"response": "Welcome to EcoWave!",
"enabled": true
}
]
}/inbound/keywordsCreate exact, starts-with, or contains matching.
inbound:writeRequest Body & Response Schemas
{
"keyword": "START",
"response": "Welcome to EcoWave! Your subscription is active.",
"matchType": "exact",
"sender": "EcoWave",
"enabled": true
}{
"id": "kw_123",
"keyword": "START",
"matchType": "exact",
"response": "Welcome to EcoWave! Your subscription is active.",
"sender": "EcoWave",
"enabled": true,
"createdAt": "2026-08-09T10:00:00.000Z"
}Webhook deliveries
Inspect callback attempts and redrive exhausted deliveries.
/webhook-deliveriesList attempts, HTTP status, errors, and DLQ entries.
webhooks:readRequest Body & Response Schemas
{
"data": [
{
"id": "wh_123",
"messageId": "msg_456",
"event": "message.delivered",
"url": "https://example.com/webhook",
"status": "delivered",
"attempts": 1,
"responseStatus": 200,
"createdAt": "2026-08-09T10:00:00.000Z"
}
]
}/webhook-deliveries/{deliveryId}/redriveReset and requeue a failed delivery.
webhooks:writeRequest Body & Response Schemas
{ "id": "wh_123", "status": "pending" }Scheduled messages
One-time or recurring sends via the scheduled queue.
/messages/scheduleSchedule with scheduleType, startsAt, timezone, and optional recurrence.
schedules:writeRequest Body & Response Schemas
{
"to": "+251911234567",
"text": "Your weekly report is available.",
"from": "EcoWave",
"scheduleType": "recurring",
"startsAt": "2026-08-11T09:00:00Z",
"timezone": "Africa/Addis_Ababa",
"recurrence": { "unit": "week", "interval": 1 }
}{
"id": "sch_123",
"status": "active",
"nextRunAt": "2026-08-11T09:00:00.000Z",
"runCount": 0
}/message-schedulesList schedules, next runs, and run counts.
schedules:readRequest Body & Response Schemas
{
"data": [
{
"id": "sch_123",
"recipient": "+251911234567",
"content": "Your weekly report is available.",
"status": "active",
"nextRunAt": "2026-08-11T09:00:00.000Z"
}
]
}Contacts
Manage recipients, verification, and CSV import/export.
/contactsSearch contacts. Limit 1–500.
contacts:readRequest Body & Response Schemas
{
"data": [
{
"id": "cnt_123",
"phoneNumber": "+251911998877",
"firstName": "Abebe",
"lastName": "Bikila",
"email": "[email protected]",
"company": "EcoWave",
"tags": ["vip", "developer"],
"customFields": { "city": "Addis Ababa" },
"createdAt": "2026-08-09T10:00:00.000Z"
}
]
}/contactsCreate an E.164 contact with optional fields and tags.
contacts:writeRequest Body & Response Schemas
{
"phoneNumber": "+251911998877",
"firstName": "Abebe",
"lastName": "Bikila",
"email": "[email protected]",
"company": "EcoWave",
"tags": ["vip", "developer"],
"customFields": { "city": "Addis Ababa" }
}{
"id": "cnt_123",
"phoneNumber": "+251911998877",
"firstName": "Abebe",
"lastName": "Bikila",
"email": "[email protected]",
"company": "EcoWave",
"tags": ["vip", "developer"],
"customFields": { "city": "Addis Ababa" },
"createdAt": "2026-08-09T10:00:00.000Z"
}/contacts/{contactId}Update fields. Changing phone clears verification.
contacts:writeRequest Body & Response Schemas
{
"phoneNumber": "+251911998877",
"firstName": "Abebe",
"lastName": "Bikila",
"company": "EcoWave Inc."
}{
"id": "cnt_123",
"firstName": "Abebe",
"lastName": "Bikila",
"company": "EcoWave Inc.",
"updatedAt": "2026-08-09T10:10:00.000Z"
}Phonebooks
Reusable contact groups for bulk sends.
/contact-listsList phonebooks and contact counts.
phonebooks:readRequest Body & Response Schemas
{
"data": [
{
"id": "lst_123",
"name": "VIP Customers",
"contactCount": 1500,
"createdAt": "2026-08-01T00:00:00.000Z"
}
]
}/contact-listsCreate a uniquely named phonebook.
phonebooks:writeRequest Body & Response Schemas
{
"name": "VIP Customers",
"description": "High value contact group"
}{
"id": "lst_123",
"name": "VIP Customers",
"description": "High value contact group",
"contactCount": 0,
"createdAt": "2026-08-09T10:00:00.000Z"
}Bulk SMS
Fan out a campaign to a phonebook via the bulk queue.
/bulk-smsSubmit or schedule a batch.
bulk:writeRequest Body & Response Schemas
{
"campaignId": "cmp_123",
"contactListId": "lst_123",
"text": "Hello {{FIRST_NAME}}, your weekly discount code is {{CODE}}.",
"scheduledAt": "2026-08-11T09:00:00Z"
}{
"id": "blk_123",
"status": "scheduled",
"recipientCount": 1500,
"scheduledAt": "2026-08-11T09:00:00.000Z"
}