EcoWave Docs

API v1

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.

Interactive OpenAPI / Swagger Docs

You can also test endpoints interactively via Swagger UI at https://ecowave-api.builds.et/docs or download the OpenAPI spec at https://ecowave-api.builds.et/openapi.json.

API credentials

Manage organization API keys from an authenticated console session.

4 endpoints
GET/api-keys

List keys, environments, scopes, usage, and expiry.

owner/admin session
Request Body & Response Schemas
Response Example (JSON)
responseJSON Response
{
  "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"
    }
  ]
}
POST/api-keys

Create a test or live key. The full secret is returned once.

owner/admin session
Request Body & Response Schemas
Request Body (JSON)
requestJSON Request
{
  "organizationId": "org_abc",
  "name": "Backend Integration Key",
  "environment": "live",
  "permissions": ["messages:send", "messages:read", "webhooks:read"]
}
Response Example (JSON)
responseJSON Response
{
  "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"
}
PATCH/api-keys/{keyId}

Update name, metadata, expiration, or permissions.

owner/admin session
Request Body & Response Schemas
Request Body (JSON)
requestJSON Request
{
  "organizationId": "org_abc",
  "name": "Updated Service Key",
  "permissions": ["messages:send", "messages:read", "contacts:read"]
}
Response Example (JSON)
responseJSON Response
{
  "id": "key_12345",
  "name": "Updated Service Key",
  "permissions": ["messages:send", "messages:read", "contacts:read"],
  "updatedAt": "2026-08-09T10:05:00.000Z"
}
DELETE/api-keys/{keyId}

Revoke a key immediately.

owner/admin session
Request Body & Response Schemas
Response Example (JSON)
responseJSON Response
HTTP 204 No Content

Security codes

Generate, deliver, and verify one-time codes for login, two-factor authentication, transactions, and custom flows.

2 endpoints
POST/security-codes/send

Generate and send a code by SMS. Supports configurable format, lifetime, attempts, templates, metadata, and Idempotency-Key.

security-codes:send
Request Body & Response Schemas
Request Body (JSON)
requestJSON Request
{
  "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" }
}
Response Example (JSON)
responseJSON Response
{
  "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"
}
POST/security-codes/verify

Verify a submitted code. A code can only succeed once and is locked after its configured attempt limit.

security-codes:verify
Request Body & Response Schemas
Request Body (JSON)
requestJSON Request
{
  "verificationId": "7f8d9e1a-4b2c-4d5e-9f01-234567890abc",
  "code": "482913"
}
Response Example (JSON)
responseJSON Response
{
  "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.

2 endpoints
GET/sender-ids

List requested, approved, and rejected sender IDs.

sender-ids:read
Request Body & Response Schemas
Response Example (JSON)
responseJSON Response
{
  "data": [
    {
      "id": "snd_123",
      "value": "EcoWave",
      "status": "approved",
      "useCase": "Transactional OTPs and alerts",
      "createdAt": "2026-08-01T00:00:00.000Z"
    }
  ]
}
POST/sender-ids

Submit a sender ID with use case and sample content.

sender-ids:write
Request Body & Response Schemas
Request Body (JSON)
requestJSON Request
{
  "value": "MyBrand",
  "useCase": "Order notifications and verification codes",
  "sampleContent": "Your code for MyBrand is 123456."
}
Response Example (JSON)
responseJSON Response
{
  "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.

3 endpoints
POST/messages

Enqueue one SMS. Supports to, text, from, metadata, webhook, and Idempotency-Key.

messages:send
Request Body & Response Schemas
Request Body (JSON)
requestJSON Request
{
  "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"
  }
}
Response Example (JSON)
responseJSON Response
{
  "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
}
GET/messages

List recent messages. Returns data and nextCursor. Limit 1–100.

messages:read
Request Body & Response Schemas
Response Example (JSON)
responseJSON Response
{
  "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
}
GET/messages/{messageId}

Get content, segments, provider IDs, errors, and timestamps.

messages:read
Request Body & Response Schemas
Response Example (JSON)
responseJSON Response
{
  "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.

4 endpoints
GET/inbound/messages

List inbound messages by processing state.

inbound:read
Request Body & Response Schemas
Response Example (JSON)
responseJSON Response
{
  "data": [
    {
      "id": "inb_123",
      "from": "+251911234567",
      "to": "EcoWave",
      "text": "START",
      "status": "processed",
      "receivedAt": "2026-08-09T10:00:00.000Z"
    }
  ]
}
POST/inbound/messages/{messageId}/redrive

Requeue a failed inbound message.

inbound:write
Request Body & Response Schemas
Response Example (JSON)
responseJSON Response
{ "id": "inb_123", "status": "received" }
GET/inbound/keywords

List keyword rules.

inbound:read
Request Body & Response Schemas
Response Example (JSON)
responseJSON Response
{
  "data": [
    {
      "id": "kw_123",
      "keyword": "START",
      "matchType": "exact",
      "response": "Welcome to EcoWave!",
      "enabled": true
    }
  ]
}
POST/inbound/keywords

Create exact, starts-with, or contains matching.

inbound:write
Request Body & Response Schemas
Request Body (JSON)
requestJSON Request
{
  "keyword": "START",
  "response": "Welcome to EcoWave! Your subscription is active.",
  "matchType": "exact",
  "sender": "EcoWave",
  "enabled": true
}
Response Example (JSON)
responseJSON Response
{
  "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.

2 endpoints
GET/webhook-deliveries

List attempts, HTTP status, errors, and DLQ entries.

webhooks:read
Request Body & Response Schemas
Response Example (JSON)
responseJSON Response
{
  "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"
    }
  ]
}
POST/webhook-deliveries/{deliveryId}/redrive

Reset and requeue a failed delivery.

webhooks:write
Request Body & Response Schemas
Response Example (JSON)
responseJSON Response
{ "id": "wh_123", "status": "pending" }

Scheduled messages

One-time or recurring sends via the scheduled queue.

2 endpoints
POST/messages/schedule

Schedule with scheduleType, startsAt, timezone, and optional recurrence.

schedules:write
Request Body & Response Schemas
Request Body (JSON)
requestJSON Request
{
  "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 }
}
Response Example (JSON)
responseJSON Response
{
  "id": "sch_123",
  "status": "active",
  "nextRunAt": "2026-08-11T09:00:00.000Z",
  "runCount": 0
}
GET/message-schedules

List schedules, next runs, and run counts.

schedules:read
Request Body & Response Schemas
Response Example (JSON)
responseJSON Response
{
  "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.

3 endpoints
GET/contacts

Search contacts. Limit 1–500.

contacts:read
Request Body & Response Schemas
Response Example (JSON)
responseJSON Response
{
  "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"
    }
  ]
}
POST/contacts

Create an E.164 contact with optional fields and tags.

contacts:write
Request Body & Response Schemas
Request Body (JSON)
requestJSON Request
{
  "phoneNumber": "+251911998877",
  "firstName": "Abebe",
  "lastName": "Bikila",
  "email": "[email protected]",
  "company": "EcoWave",
  "tags": ["vip", "developer"],
  "customFields": { "city": "Addis Ababa" }
}
Response Example (JSON)
responseJSON Response
{
  "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"
}
PATCH/contacts/{contactId}

Update fields. Changing phone clears verification.

contacts:write
Request Body & Response Schemas
Request Body (JSON)
requestJSON Request
{
  "phoneNumber": "+251911998877",
  "firstName": "Abebe",
  "lastName": "Bikila",
  "company": "EcoWave Inc."
}
Response Example (JSON)
responseJSON Response
{
  "id": "cnt_123",
  "firstName": "Abebe",
  "lastName": "Bikila",
  "company": "EcoWave Inc.",
  "updatedAt": "2026-08-09T10:10:00.000Z"
}

Phonebooks

Reusable contact groups for bulk sends.

2 endpoints
GET/contact-lists

List phonebooks and contact counts.

phonebooks:read
Request Body & Response Schemas
Response Example (JSON)
responseJSON Response
{
  "data": [
    {
      "id": "lst_123",
      "name": "VIP Customers",
      "contactCount": 1500,
      "createdAt": "2026-08-01T00:00:00.000Z"
    }
  ]
}
POST/contact-lists

Create a uniquely named phonebook.

phonebooks:write
Request Body & Response Schemas
Request Body (JSON)
requestJSON Request
{
  "name": "VIP Customers",
  "description": "High value contact group"
}
Response Example (JSON)
responseJSON Response
{
  "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.

1 endpoints
POST/bulk-sms

Submit or schedule a batch.

bulk:write
Request Body & Response Schemas
Request Body (JSON)
requestJSON Request
{
  "campaignId": "cmp_123",
  "contactListId": "lst_123",
  "text": "Hello {{FIRST_NAME}}, your weekly discount code is {{CODE}}.",
  "scheduledAt": "2026-08-11T09:00:00Z"
}
Response Example (JSON)
responseJSON Response
{
  "id": "blk_123",
  "status": "scheduled",
  "recipientCount": 1500,
  "scheduledAt": "2026-08-11T09:00:00.000Z"
}