Introduction

The shape of the API at a glance: base URL, bearer auth, status codes, rate limits, and how keys map to capabilities.

Design influences

Sevk's API surface and developer experience follow patterns established by leading email platforms in this space: bearer auth, capability-scoped keys, audience/segment/broadcast modeling, and the conventional shape of send endpoints. These conventions have become de facto standards because they work, and we adopt them so developers familiar with the ecosystem feel at home.

Sevk is an independent implementation. Our ownership model, billing system, analytics pipeline, SMTP proxy, and dashboard are built from the ground up. Where industry conventions serve developers well, we follow them; where we can do better, we depart.

Beyond the API, our goal is a product that is just as usable for non-developers. Marketers, founders, and operators should be able to verify a domain, design an email with the visual editor or describe it to an AI, target an audience or segment, and ship a campaign without ever opening a terminal. The SDK and CLI are the developer surface; the dashboard is the end-user surface. Both work against the same primitives, so a campaign authored in one is fully editable in the other.

Base URL

Sevk exposes a single REST endpoint. Every request must be made over TLS. Plaintext HTTP connections are rejected at the edge and there is no fallback. Send all calls to:

https://api.sevk.io

Requests and responses are JSON. Endpoints are versionless; we ship additive changes only and announce any breaking change in the changelog before it lands.

Authentication

Sevk uses bearer tokens. Issue an API key from the dashboard, then attach it to every request via the Authorization header. Keys are scoped to a single project and carry the capabilities you selected at creation time. See the API Key reference.

Authorization: Bearer sevk_xxxxxxxxx

Treat keys as secrets. Never embed them in mobile apps, browser bundles, or public repos. Use environment variables on the server side and rotate compromised keys from the dashboard.

Response codes

Status codes follow the usual convention: 2xx means the operation completed, 4xx means something about the request needs attention from your side, and 5xx means we dropped the ball. Retry with backoff and the issue will surface in our status page.

StatusDescription
200Successful request.
400Check that the parameters were correct.
401The API key used was missing.
403The API key used was invalid.
404The resource was not found.
429The rate limit was exceeded.
500Internal server error.

Rate limit

Each project has its own per-second rate limit on the send endpoints. New projects start with a conservative default; the cap is configured per project, so if you have a workload that needs more throughput we can raise it for you. Bursts above the project's ceiling return 429 Too Many Requests with a Retry-After header indicating when to try again.

Need a higher cap? Open a Quota Increase request from the dashboard with rate_limit as the subtype and the throughput you need. For workloads that legitimately push the ceiling (bulk imports, large broadcasts), prefer the dedicated bulk endpoints over hand-rolled fan-out and apply exponential backoff in your client.

FAQ

How do I get an API key?

Open the dashboard, switch to the project you want the key to act on, then go to Settings → API Keys → Create. The full secret is shown exactly once at creation: copy it into your secret store immediately.

What permissions does my API key have?

Whatever you grant it. Two modes are available when you create a key:

  • Full access: every capability the project supports, no restrictions.
  • Scoped: pick exactly the resources and verbs the key needs (e.g. email:send only, or read-only access to contacts).

We strongly recommend scoped keys for any key that ships into production. A leaked send-only key cannot drain your contact list.

Can I lock a key to specific sender domains?

Yes. Each key can be pinned to one or more verified domains in the same project. Sends from any other domain are rejected with 403, even if the key has email:send. Leave the list empty for the default behavior (any domain in the project). Useful when one repo handles transactional fromapp.example.com and another handles marketing from news.example.com: give each its own key locked to its own domain so a leaked key cannot impersonate the other surface.