Skip to content
DashboardRequest access

API Overview

The REST API backs both the SDK and the CLI. Most integrations should use the SDK Reference instead of calling routes directly — this page covers the pieces every request shares.

Base URL

The hosted API is at https://develemail.com/api. Self-hosted instances listen on http://localhost:3001 in development; use the URL of your deployed API in production.

Authentication

Send your API key as a bearer token on every request:

Authorization: Bearer <your-api-key>

Create a key with devel key create --project <id> --name <name> (see the CLI Reference) or from a project's page in the dashboard. Requests without a valid Authorization header return 401 Unauthorized.

Errors

Failed requests return a JSON body shaped like:

{
  "statusCode": 401,
  "error": "Unauthorized",
  "message": "Missing or invalid Authorization header"
}

Send-related failures carry a machine-readable error code:

StatuserrorMeaning
400reserved_recipient_domainA recipient is on a reserved domain
400mixed_sandbox_recipientsOne send mixes sandbox and real recipients
403domain_not_verifiedThe sender domain isn't verified yet
403sending_restrictedSending is restricted for this account
403organization_suspendedThe organization is suspended
413attachment_too_largeAn attachment exceeds the size limit
429quota_exceededMonthly quota used up; Retry-After is set
429daily_limit_exceededDaily tier limit reached; Retry-After is set

When billing is enabled on the instance, a quota_exceeded response also includes upgrade_url, a link to the dashboard billing page where an org admin can pick a larger plan.

The SDK parses this automatically and throws DevelEmailError with status, message, and code (from the error field) — see the "Error handling" section of the SDK Reference.

Retries

The API returns 429 when you're rate-limited and 5xx for transient failures. Both are safe to retry; the SDK does this automatically with exponential backoff, respecting Retry-After when present.

Idempotency

POST /v1/emails, POST /v1/emails/batch, POST /v1/sms and POST /v1/sms/batch accept an Idempotency-Key header. Retrying the same key returns the original result instead of sending a duplicate. The SDK generates one for you unless you pass options.idempotencyKey explicitly. Email and SMS keys live in separate namespaces, so the same key on /v1/emails and /v1/sms doesn't collide.

List queries

Resourcelimit maxNotes
Emails200recipient up to 320 chars, subject up to 200
Contacts200search up to 200 chars
Lists200
SMS200cursor-paginated
Campaigns100default 50

A limit above the cap, or an email status filter that isn't one of the email statuses, returns 400. In search strings, % and _ match literally rather than as wildcards.