FlowSender External API (1.0.0-pending)

Download OpenAPI specification:

URL: https://flowsender.app/ License: LicenseRef-FlowSender-Proprietary

Workspace-scoped automation for FlowSender campaigns and leads.

The FlowSender external API is a server-to-server interface pending its first production release. A workspace administrator creates a named API key in the Developer page; the raw secret is displayed only once. Never embed a key in browser or mobile code, paste it into a documentation site, or log it. Send it only to FlowSender over HTTPS.

The API key determines the workspace. Requests cannot select or override workspace_id. API keys work only on the documented /api/v1 routes and are rejected by the browser-session /api surface. Browser sessions are rejected by /api/v1.

API v1 permits additive endpoints and optional fields. Removing or renaming an endpoint or field, changing its type or meaning, tightening accepted validation, or changing authentication is breaking and requires a new path-major. A deprecated major is supported for at least 180 days and returns Deprecation, Sunset, and migration-guide Link headers. FlowSender supports at most two majors concurrently unless a documented, time-bounded exception applies.

Collection cursors are opaque, signed, filter-bound, and valid for 24 hours. Do not parse them. Restart without a cursor after cursor_expired. Every response includes X-Request-ID.

Campaigns

Read campaign configuration and status.

List campaigns

Returns campaigns ordered by created_at DESC, id DESC within the key's workspace.

Authorizations:
apiKey
query Parameters
limit
integer [ 1 .. 100 ]
Default: 50

Page size; defaults to 50 and cannot exceed 100.

cursor
string non-empty

Opaque cursor from the previous page, valid for 24 hours and bound to filters and order.

status
string (CampaignStatus)
Enum: "draft" "active" "paused" "archived"

Filter by campaign status.

q
string <= 200 characters

Case-insensitive campaign-name search.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "page": {
    }
}

Get campaign status

Returns campaign configuration, status, and aggregate enrollment and send counts.

Authorizations:
apiKey
path Parameters
campaign_id
required
integer <int64> >= 1

Workspace campaign identifier.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

List campaign steps

Returns steps ordered by step_index ASC, id ASC.

Authorizations:
apiKey
path Parameters
campaign_id
required
integer <int64> >= 1

Workspace campaign identifier.

query Parameters
limit
integer [ 1 .. 100 ]
Default: 50

Page size; defaults to 50 and cannot exceed 100.

cursor
string non-empty

Opaque cursor from the previous page, valid for 24 hours and bound to filters and order.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "page": {
    }
}

List enrolled leads

Returns enrollments ordered by enrollment creation time descending, then ID descending.

Authorizations:
apiKey
path Parameters
campaign_id
required
integer <int64> >= 1

Workspace campaign identifier.

query Parameters
limit
integer [ 1 .. 100 ]
Default: 50

Page size; defaults to 50 and cannot exceed 100.

cursor
string non-empty

Opaque cursor from the previous page, valid for 24 hours and bound to filters and order.

status
string (EnrollmentStatus)
Enum: "active" "paused" "replied" "completed" "bounced"

Filter by enrollment status.

mailbox_provider_family
string
Enum: "google" "microsoft" "yahoo" "custom" "unknown"

Filter by detected mailbox-provider family.

q
string <= 200 characters

Search lead email or custom fields.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "page": {
    }
}

Leads

Read and import workspace leads.

List enrolled leads

Returns enrollments ordered by enrollment creation time descending, then ID descending.

Authorizations:
apiKey
path Parameters
campaign_id
required
integer <int64> >= 1

Workspace campaign identifier.

query Parameters
limit
integer [ 1 .. 100 ]
Default: 50

Page size; defaults to 50 and cannot exceed 100.

cursor
string non-empty

Opaque cursor from the previous page, valid for 24 hours and bound to filters and order.

status
string (EnrollmentStatus)
Enum: "active" "paused" "replied" "completed" "bounced"

Filter by enrollment status.

mailbox_provider_family
string
Enum: "google" "microsoft" "yahoo" "custom" "unknown"

Filter by detected mailbox-provider family.

q
string <= 200 characters

Search lead email or custom fields.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "page": {
    }
}

List leads

Returns leads ordered by created_at DESC, id DESC; message history is omitted.

Authorizations:
apiKey
query Parameters
limit
integer [ 1 .. 100 ]
Default: 50

Page size; defaults to 50 and cannot exceed 100.

cursor
string non-empty

Opaque cursor from the previous page, valid for 24 hours and bound to filters and order.

status
string (LeadStatus)
Enum: "active" "replied" "bounced"

Filter by lead status.

mailbox_provider_family
string
Enum: "google" "microsoft" "yahoo" "custom" "unknown"

Filter by detected mailbox-provider family.

q
string <= 200 characters

Search lead email or custom fields.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "page": {
    }
}

Get a lead

Returns lead and enrollment data; unibox and message history are intentionally omitted.

Authorizations:
apiKey
path Parameters
lead_id
required
integer <int64> >= 1

Workspace lead identifier.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Import leads

Imports leads from JSON or CSV and omits FlowSender's internal object-storage key. This operation requires Idempotency-Key. Equivalent canonical JSON, or multipart requests with equivalent fields and file bytes, share a fingerprint regardless of JSON object order, multipart boundary, field order, or filename. Completed 2xx and deterministic 4xx responses replay for 24 hours. 408, 429, and 5xx are not cached. Reuse for different content returns idempotency_key_reused; concurrent duplicates return idempotency_in_progress.

Authorizations:
apiKey
header Parameters
Idempotency-Key
required
string [ 8 .. 255 ] characters ^[ -~]+$
Example: 018f8f5e-6c4a-7d27-a6f1-fake12345678

New 8–255 character printable ASCII value for each intended operation, retained for 24 hours.

Request Body schema:
required
object
required
Array of objects non-empty

Responses

Request samples

Content type
{
  • "mapping": {
    },
  • "rows": [
    ]
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Analytics

Read workspace and campaign delivery analytics.

Get analytics summary

Returns totals, daily buckets, and campaign summaries for an inclusive UTC date range.

Authorizations:
apiKey
query Parameters
from
required
string <date>

First date in the inclusive UTC range.

to
required
string <date>

Last date in the inclusive UTC range.

campaign_id
integer <int64> >= 1

Restrict results to one campaign.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Enrollments

Enroll existing workspace leads into a campaign.

Enroll existing leads

Enrolls existing leads transactionally and requires Idempotency-Key.

Authorizations:
apiKey
path Parameters
campaign_id
required
integer <int64> >= 1

Workspace campaign identifier.

header Parameters
Idempotency-Key
required
string [ 8 .. 255 ] characters ^[ -~]+$
Example: 018f8f5e-6c4a-7d27-a6f1-fake12345678

New 8–255 character printable ASCII value for each intended operation, retained for 24 hours.

Request Body schema: application/json
required
lead_ids
required
Array of integers <int64> [ 1 .. 500 ] items unique [ items <int64 > >= 1 ]

Responses

Request samples

Content type
application/json
{
  • "lead_ids": [
    ]
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Webhooks

Outbound event contract; webhook administration remains browser-only.

Receive a reply event Webhook

Receiver-side contract example for an inbound lead reply.

header Parameters
X-FlowSender-Delivery-ID
required
string <uuid>

Stable logical-delivery UUID, unchanged across retries and suitable for deduplication.

X-FlowSender-Event
required
string (EventName)
Enum: "reply_received" "step_sent" "bounce_detected" "enrollment_completed"

Event name matching the envelope.

X-FlowSender-Timestamp
required
integer <int64>

Unix seconds regenerated for every attempt; reject timestamps more than five minutes old.

X-FlowSender-Signature
required
string^v1=[0-9a-f]{64}(,v1=[0-9a-f]{64})?$

One or two comma-separated v1=<lowercase hex> HMAC-SHA256 values. Compute HMAC using the webhook secret over timestamp + "." + raw_body, where timestamp is the exact timestamp header and raw_body is the unmodified request byte sequence. Parse no JSON before verification. Compare in constant time and reject timestamps over five minutes old. During the seven-day rotation overlap, accept a match against either receiver secret.

Request Body schema: application/json
required
id
required
string <uuid>

Stable across delivery retries.

version
required
integer
Value: 1
event
required
string
Enum: "reply_received" "step_sent" "bounce_detected" "enrollment_completed"
Value: "reply_received"
occurred_at
required
string <date-time>
workspace_id
required
integer <int64>
required
object

Responses

Request samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "version": 1,
  • "event": "reply_received",
  • "occurred_at": "2019-08-24T14:15:22Z",
  • "workspace_id": 0,
  • "data": {
    }
}

Receive a sent-step event Webhook

Receiver-side contract example for an email step sent by FlowSender.

header Parameters
X-FlowSender-Delivery-ID
required
string <uuid>

Stable logical-delivery UUID, unchanged across retries and suitable for deduplication.

X-FlowSender-Event
required
string (EventName)
Enum: "reply_received" "step_sent" "bounce_detected" "enrollment_completed"

Event name matching the envelope.

X-FlowSender-Timestamp
required
integer <int64>

Unix seconds regenerated for every attempt; reject timestamps more than five minutes old.

X-FlowSender-Signature
required
string^v1=[0-9a-f]{64}(,v1=[0-9a-f]{64})?$

One or two comma-separated v1=<lowercase hex> HMAC-SHA256 values. Compute HMAC using the webhook secret over timestamp + "." + raw_body, where timestamp is the exact timestamp header and raw_body is the unmodified request byte sequence. Parse no JSON before verification. Compare in constant time and reject timestamps over five minutes old. During the seven-day rotation overlap, accept a match against either receiver secret.

Request Body schema: application/json
required
id
required
string <uuid>

Stable across delivery retries.

version
required
integer
Value: 1
event
required
string
Enum: "reply_received" "step_sent" "bounce_detected" "enrollment_completed"
Value: "step_sent"
occurred_at
required
string <date-time>
workspace_id
required
integer <int64>
required
object

Responses

Request samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "version": 1,
  • "event": "step_sent",
  • "occurred_at": "2019-08-24T14:15:22Z",
  • "workspace_id": 0,
  • "data": {
    }
}

Receive a bounce event Webhook

Receiver-side contract example for a detected delivery bounce.

header Parameters
X-FlowSender-Delivery-ID
required
string <uuid>

Stable logical-delivery UUID, unchanged across retries and suitable for deduplication.

X-FlowSender-Event
required
string (EventName)
Enum: "reply_received" "step_sent" "bounce_detected" "enrollment_completed"

Event name matching the envelope.

X-FlowSender-Timestamp
required
integer <int64>

Unix seconds regenerated for every attempt; reject timestamps more than five minutes old.

X-FlowSender-Signature
required
string^v1=[0-9a-f]{64}(,v1=[0-9a-f]{64})?$

One or two comma-separated v1=<lowercase hex> HMAC-SHA256 values. Compute HMAC using the webhook secret over timestamp + "." + raw_body, where timestamp is the exact timestamp header and raw_body is the unmodified request byte sequence. Parse no JSON before verification. Compare in constant time and reject timestamps over five minutes old. During the seven-day rotation overlap, accept a match against either receiver secret.

Request Body schema: application/json
required
id
required
string <uuid>

Stable across delivery retries.

version
required
integer
Value: 1
event
required
string
Enum: "reply_received" "step_sent" "bounce_detected" "enrollment_completed"
Value: "bounce_detected"
occurred_at
required
string <date-time>
workspace_id
required
integer <int64>
required
object

Responses

Request samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "version": 1,
  • "event": "bounce_detected",
  • "occurred_at": "2019-08-24T14:15:22Z",
  • "workspace_id": 0,
  • "data": {
    }
}

Receive an enrollment-completed event Webhook

Receiver-side contract example for completion of every campaign step.

header Parameters
X-FlowSender-Delivery-ID
required
string <uuid>

Stable logical-delivery UUID, unchanged across retries and suitable for deduplication.

X-FlowSender-Event
required
string (EventName)
Enum: "reply_received" "step_sent" "bounce_detected" "enrollment_completed"

Event name matching the envelope.

X-FlowSender-Timestamp
required
integer <int64>

Unix seconds regenerated for every attempt; reject timestamps more than five minutes old.

X-FlowSender-Signature
required
string^v1=[0-9a-f]{64}(,v1=[0-9a-f]{64})?$

One or two comma-separated v1=<lowercase hex> HMAC-SHA256 values. Compute HMAC using the webhook secret over timestamp + "." + raw_body, where timestamp is the exact timestamp header and raw_body is the unmodified request byte sequence. Parse no JSON before verification. Compare in constant time and reject timestamps over five minutes old. During the seven-day rotation overlap, accept a match against either receiver secret.

Request Body schema: application/json
required
id
required
string <uuid>

Stable across delivery retries.

version
required
integer
Value: 1
event
required
string
Enum: "reply_received" "step_sent" "bounce_detected" "enrollment_completed"
Value: "enrollment_completed"
occurred_at
required
string <date-time>
workspace_id
required
integer <int64>
required
object

Responses

Request samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "version": 1,
  • "event": "enrollment_completed",
  • "occurred_at": "2019-08-24T14:15:22Z",
  • "workspace_id": 0,
  • "data": {
    }
}