Skip to content

API Reference

The SubscribeFlow REST API follows resource-oriented design with consistent patterns across all endpoints.

Base URL

https://api.subscribeflow.net/api/v1

Authentication

Include your API key in every request. See Authentication for details.

X-API-Key: sf_live_...
Authorization: Bearer sf_live_...

Endpoints overview

Subscribers

Method Path Description
POST /subscribers Create a subscriber
GET /subscribers List subscribers
GET /subscribers/{id} Get a subscriber by ID
GET /subscribers/by-email Get a subscriber by email
PATCH /subscribers/{id} Update a subscriber
DELETE /subscribers/{id} Delete a subscriber
POST /subscribers/{id}/tags Add tags to a subscriber
DELETE /subscribers/{id}/tags/{slug} Remove a tag from a subscriber
POST /subscribers/{id}/preference-token Generate preference center token

Tags

Method Path Description
POST /tags Create a tag
GET /tags List tags
GET /tags/{id} Get a tag by ID
GET /tags/by-name Get a tag by name
PATCH /tags/{id} Update a tag
DELETE /tags/{id} Delete a tag

Templates

Method Path Description
POST /templates Create a template
GET /templates List templates
GET /templates/{id} Get a template by ID
PATCH /templates/{id} Update a template
DELETE /templates/{id} Delete a template
POST /templates/{id}/preview Preview a template with variables

Emails

Method Path Description
POST /emails/send Send a transactional email

Campaigns

Method Path Description
POST /campaigns Create a campaign
GET /campaigns List campaigns
GET /campaigns/{id} Get a campaign by ID
PATCH /campaigns/{id} Update a campaign
POST /campaigns/{id}/send Send a campaign
POST /campaigns/{id}/cancel Cancel a campaign
POST /campaigns/{id}/duplicate Duplicate a campaign
POST /campaigns/{id}/retry Retry a failed campaign
GET /campaigns/{id}/recipient-count Count matching recipients

Triggers

Method Path Description
POST /triggers Create a trigger
GET /triggers List triggers
GET /triggers/{id} Get a trigger by ID
PATCH /triggers/{id} Update a trigger
DELETE /triggers/{id} Delete a trigger

Webhooks

Method Path Description
POST /webhooks Create a webhook
GET /webhooks List webhooks
GET /webhooks/{id} Get a webhook by ID
PATCH /webhooks/{id} Update a webhook
DELETE /webhooks/{id} Delete a webhook
POST /webhooks/{id}/test Test a webhook
POST /webhooks/{id}/rotate-secret Rotate signing secret
GET /webhooks/{id}/deliveries List deliveries
POST /webhooks/{id}/deliveries/{did}/retry Retry a delivery
GET /webhooks/{id}/stats Get delivery statistics

Preference Center

Method Path Description
GET /preference-center Get subscriber preferences
POST /preference-center/tags/{id}/subscribe Subscribe to a tag
POST /preference-center/tags/{id}/unsubscribe Unsubscribe from a tag
GET /preference-center/export Export subscriber data
DELETE /preference-center/account Delete subscriber account

Billing

Method Path Description
GET /billing/subscription Get current subscription
POST /billing/checkout Create Stripe Checkout session
POST /billing/portal Create Stripe Billing Portal session
POST /billing/sync Sync subscription with Stripe

Tip

Explore the full API interactively at /docs (Swagger UI) or /redoc (ReDoc).

Error format

SubscribeFlow returns errors in RFC 7807 Problem Details format:

{
  "type": "https://docs.subscribeflow.net/errors/not-found",
  "title": "Not Found",
  "status": 404,
  "detail": "Subscriber with ID 'abc-123' not found.",
  "instance": "/api/v1/subscribers/abc-123"
}

Error codes

Status Name Description
400 Bad Request Malformed request syntax
401 Unauthorized Missing or invalid API key
402 Payment Required Plan limit exceeded (upgrade required)
404 Not Found Resource does not exist
409 Conflict Resource already exists (e.g. duplicate email)
422 Unprocessable Entity Request body failed validation
429 Too Many Requests Rate limit exceeded
500 Internal Server Error Unexpected server error

Pagination

List endpoints use cursor-based pagination with two query parameters:

Parameter Type Default Description
cursor string null Cursor from a previous response
limit integer 50 Number of items per page (max 100)

The response includes an X-Total-Count header with the total number of matching resources.

{
  "items": [...],
  "cursor": "eyJpZCI6IjEyMyJ9",
  "total": 1250
}

Pass the cursor value to the next request to fetch the following page. When cursor is null, you have reached the last page.

Rate limiting

All API keys are limited to 1,000 requests per minute. Rate limit status is included in every response:

Header Description
X-RateLimit-Limit Maximum requests per minute (1000)
X-RateLimit-Remaining Requests remaining in the current window
X-RateLimit-Reset Unix timestamp when the window resets

When you exceed the limit, the API returns HTTP 429 with a Retry-After header indicating how many seconds to wait.

from subscribeflow import RateLimitError

try:
    await client.subscribers.list()
except RateLimitError:
    print("Rate limit hit -- wait and retry")
import { SubscribeFlowError } from '@subscribeflow/sdk';

try {
  await client.subscribers.list();
} catch (error) {
  if (error instanceof SubscribeFlowError && error.status === 429) {
    console.log('Rate limit hit -- wait and retry');
  }
}
# Check rate limit headers in the response:
# X-RateLimit-Limit: 1000
# X-RateLimit-Remaining: 998
# X-RateLimit-Reset: 1710000060