284 endpoints in API version 0.1.0, generated fromapi/openapi.yaml. Your instance serves the exact contract it runs at /v1/openapi.yaml. Download this copy to generate a client or import it into an API tool.
Endpoints marked Public need no credentials. All others take an API token (Authorization: Bearer oft_...) or a session cookie; see Authentication.{ws} is a workspace ID.
System and discovery
get/healthz
Liveness check
Public
Responses: 200 The process is up
get/readyz
Readiness check, including the database
Public
Responses: 200 Ready to serve traffic, 503 A dependency is unavailable
get/v1/openapi.yaml
This document
Public
Responses: 200 The OpenAPI document
get/.well-known/outflare.json
Machine-readable discovery for agents and tools
Public
Responses: 200 Discovery document
Setup, auth, workspaces and access
get/v1/setup
Whether first-run setup is still needed
Public
Responses: 200 Setup status
post/v1/setup
Create the first user and workspace
Public
Only works while the instance has no users. Signs the new owner in.
| Parameter | In | Type | Description |
|---|
email * | body | string, email | |
name * | body | string | |
password * | body | string | |
workspace_name * | body | string | |
telemetry | body | boolean | false turns off anonymous usage stats and update checks from the start. Default true. |
Responses: 201 Created; a session cookie is set, 409 Error
post/v1/auth/login
Sign in with email and password
Public
Sets a session cookie. Ten failed attempts for one email lock it for 15 minutes.
| Parameter | In | Type | Description |
|---|
email * | body | string | |
password * | body | string | |
Responses: 200 Signed in, 401 Error, 429 Error
post/v1/auth/logout
End the current session
Signed in
Responses: 204 Signed out
post/v1/auth/password-reset
Email a password reset link
Public
Sends a one-time link (valid an hour) to <PUBLIC_URL>/reset-password#<token>, through the account email service
(see account_email in /v1/meta). The answer is the same whether or not the email has an account. Ten requests
for one email, or from one network, in 15 minutes are refused.
| Parameter | In | Type | Description |
|---|
email * | body | string | |
Responses: 202 Sent, 400 Error, 429 Error
post/v1/auth/password-reset/confirm
Choose a new password with a reset link
Public
Sets the password, signs out every session, signs this browser in, and counts the email as confirmed.
| Parameter | In | Type | Description |
|---|
token * | body | string | The part of the link after #. |
password * | body | string | |
Responses: 200 Password changed and signed in, 400 Error, 404 Error
post/v1/auth/verify-email
Confirm an email address with its link
Public
The link is <PUBLIC_URL>/verify-email#<token>, valid 48 hours, sent when an account is made with a password.
| Parameter | In | Type | Description |
|---|
token * | body | string | |
Responses: 200 Confirmed, 404 Error
post/v1/me/email-verification
Send the confirmation link again
Signed in
Replaces any earlier link. Answers 200 without sending when the address is already confirmed.
Responses: 200 Already confirmed, 202 Sent, 429 Error, 502 Error
post/v1/auth/passkey/options
Start signing in with a passkey
Public
Returns WebAuthn request options (publicKey) for navigator.credentials.get, with no allowed credentials so the
browser offers whichever passkeys it holds for this site. Sets a short-lived outflare_passkey cookie holding the
challenge. Passkeys are on when PUBLIC_URL is https (or PASSKEYS=on); passkey is then in login_methods.
Responses: 200 Options for the browser, 404 Error
post/v1/auth/passkey
Finish signing in with a passkey
Public
The body is the browser's assertion (PublicKeyCredential.toJSON()). Sets a session cookie.
Responses: 200 Signed in, 400 Error, 401 Error, 404 Error, 429 Error
get/v1/me/passkeys
Your passkeys
Signed in
Responses: 200 Passkeys that sign you in, 404 Error
post/v1/me/passkeys
Save a new passkey
Signed in
The body is the browser's new credential (PublicKeyCredential.toJSON()), answering /v1/me/passkeys/options.
| Parameter | In | Type | Description |
|---|
name | query | string | A label, such as "MacBook". Default Passkey. |
Responses: 201 Saved, 400 Error
post/v1/me/passkeys/options
Start adding a passkey
Signed in
Returns WebAuthn creation options (publicKey) for navigator.credentials.create, and sets the outflare_passkey challenge cookie. Up to 10 passkeys.
Responses: 200 Options for the browser, 404 Error, 409 Error
patch/v1/me/passkeys/{id}
Rename a passkey
Signed in
| Parameter | In | Type | Description |
|---|
id * | path | string, uuid | |
name * | body | string | |
Responses: 200 Renamed, 404 Error
delete/v1/me/passkeys/{id}
Remove a passkey
Signed in
| Parameter | In | Type | Description |
|---|
id * | path | string, uuid | |
Responses: 204 Removed. It no longer signs you in, 404 Error
get/v1/auth/google/start
Start "Continue with Google"
Public
Redirects to Google's sign-in screen (scopes openid, email, profile only). Open it in the browser, not with fetch.
Needs GOOGLE_OAUTH_CLIENT_ID/SECRET, with <PUBLIC_URL>/v1/auth/google/callback added to the client's redirect URIs.
Google then returns to the callback, which signs the person in to the account linked to that Google account, or the
account with the same verified email. Nobody gets an account from Google alone: an unknown person is sent back to
return with identity (valid 15 minutes), identity_email and identity_name, and the invite page redeems
identity instead of a password. Errors come back as login_error.
| Parameter | In | Type | Description |
|---|
return | query | string | Path on this site to come back to, such as /invite#<token>. Default /. |
Responses: 302 To Google, 404 Error
get/v1/auth/google/callback
Google's return from "Continue with Google"
Public
Called by Google, not by clients. Redirects to the app, or back to return with identity or login_error.
Responses: 302 Back to the app
post/v1/invites/accept
Accept a workspace invite
Public
A new email creates an account (name and password required). An existing account must give its password, or be
signed in already. Instead of a password, identity from "Continue with Google" proves the invited email; a new
account made that way has no password and signs in with Google.
| Parameter | In | Type | Description |
|---|
token * | body | string | |
name | body | string | |
password | body | string | |
identity | body | string | The identity parameter from the Google sign-in callback. |
Responses: 200 Joined; a session cookie is set, 401 Error, 404 Error
get/v1/me
The signed-in user and their workspaces
Signed in
Responses: 200 Current user
post/v1/workspaces
Create a workspace owned by the signed-in user
Signed in
| Parameter | In | Type | Description |
|---|
name * | body | string | |
Responses: 201 Created
get/v1/workspaces/{ws}
Get a workspace
Scope: workspace.read
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 200 The workspace, 404 Error
get/v1/workspaces/{ws}/members
List members
Scope: members.read
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 200 Members, oldest first
patch/v1/workspaces/{ws}/members/{user}
Change a member's role
Scope: members.manage.
Nobody can act above their own role; only owners can grant or change owner; the last owner cannot be demoted.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
user * | path | string, uuid | |
role * | body | "owner" | "admin" | "operator" | "viewer" | |
Responses: 200 Updated, 403 Error, 409 Error
delete/v1/workspaces/{ws}/members/{user}
Remove a member
Scope: members.manage
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
user * | path | string, uuid | |
Responses: 204 Removed, 409 Error
get/v1/workspaces/{ws}/invites
List pending invites
Scope: members.manage
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 200 Pending invites, newest first
post/v1/workspaces/{ws}/invites
Invite someone by email
Scope: members.manage.
The token and link are returned once; they expire after 7 days.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
email * | body | string, email | |
role * | body | "admin" | "operator" | "viewer" | |
Responses: 201 Created
delete/v1/workspaces/{ws}/invites/{id}
Revoke a pending invite
Scope: members.manage
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 204 Revoked
get/v1/workspaces/{ws}/api-tokens
List active API tokens
Scope: tokens.manage.
Secrets are never returned after creation.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 200 Tokens, newest first
post/v1/workspaces/{ws}/api-tokens
Create a scoped API token
Scope: tokens.manage.
A token cannot hold scopes or looser limits than its creator. The secret is returned once.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
name * | body | string | |
scopes * | body | "workspace.read" | "members.read" | "members.manage" | "tokens.manage" | "audit.read" | "mailboxes.read" | "mailboxes.manage" | "leads.read" | "leads.manage" | "suppressions.manage" | "sequences.read" | "sequences.manage" | "inbox.read" | "inbox.manage" | "integrations.read" | "integrations.manage" | "outcomes.read" | "outcomes.manage" | "projects.read" | "projects.manage" | "infrastructure.read" | "infrastructure.manage" | "infrastructure.approve" | "analytics.read" | "missions.read" | "missions.run" | "missions.approve"[] | |
expires_in_days | body | integer | |
daily_send_budget | body | integer | |
max_priority | body | "low" | "normal" | "high" | |
may_take_mailboxes | body | boolean | |
default_team_id | body | string, uuid | |
project_id | body | string, uuid | Binds the token to one project: it sees and changes only that project's records, and endpoints that are not project-aware refuse it. Fixed for the token's life. |
Responses: 201 Created
patch/v1/workspaces/{ws}/api-tokens/{id}
Change a token's sending and allocation limits
Scope: tokens.manage.
A token cannot change its own limits, or grant looser ones than it has. Scopes are fixed; issue a new token to change them.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
daily_send_budget | body | integer | |
max_priority | body | "low" | "normal" | "high" | |
may_take_mailboxes | body | boolean | |
default_team_id | body | string, uuid | |
Responses: 200 The token, 400 Error, 403 Error
delete/v1/workspaces/{ws}/api-tokens/{id}
Revoke an API token
Scope: tokens.manage
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 204 Revoked
get/v1/workspaces/{ws}/audit-events
Audit log, newest first
Scope: audit.read.
Page with before=next_before.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
limit | query | integer | |
before | query | integer | |
Responses: 200 Events
get/v1/workspaces/{ws}/stats
Workspace overview
Scope: workspace.read.
Mailbox health, sending and reply counts, in one call. Windows are rolling (last 24 hours, last 7 days).
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 200 Counts
instance
get/v1/instance/telemetry
Usage stats and update check for this server
Signed in
Self-hosted servers send one anonymous report a day (version,
platform, usage counts as ranges, connector ids) and get back the
newest version and any security notices. See docs/telemetry.md.
Needs a signed-in user.
Responses: 200 Telemetry and update status, 403 Error
patch/v1/instance/telemetry
Turn usage stats on or off
Signed in
Only the person who set up the server can change it. Refused with 409 when the server's environment (OUTFLARE_TELEMETRY, DO_NOT_TRACK) or the build decides.
| Parameter | In | Type | Description |
|---|
enabled * | body | boolean | |
Responses: 200 Updated status, 400 Error, 403 Error, 409 Error
get/v1/instance/telemetry/preview
The exact report this server would send
Signed in
Responses: 200 The report, not sent, 403 Error
agencies
get/v1/agencies
Agencies the signed-in user belongs to
Signed in
Responses: 200 Agencies
post/v1/agencies
Create an agency
Signed in
Signed-in users only. The creator becomes the agency's owner. Pass
workspace_ids to bring workspaces you own in as clients.
| Parameter | In | Type | Description |
|---|
name * | body | string | |
workspace_ids | body | string, uuid[] | |
Responses: 201 Created, 400 Error
get/v1/agencies/{ag}
An agency
Signed in
Agency members, or the agency's own tokens.
| Parameter | In | Type | Description |
|---|
ag * | path | string, uuid | |
Responses: 200 The agency, 404 Error
patch/v1/agencies/{ag}
Rename the agency or change its white label
Signed in
Agency admins. Client members see the brand name, logo and accent colour in place of Outflare.
| Parameter | In | Type | Description |
|---|
ag * | path | string, uuid | |
name | body | string | |
brand_name | body | string | |
logo_url | body | string | An https URL |
accent_color | body | string | |
support_email | body | string | |
Responses: 200 The agency, 400 Error
get/v1/agencies/{ag}/clients
Every client with this week's numbers
Signed in
Agency members or agency tokens. Worst bounce rate first.
| Parameter | In | Type | Description |
|---|
ag * | path | string, uuid | |
Responses: 200 Clients
post/v1/agencies/{ag}/clients
Create a client workspace, or bring in one you own
Signed in
Send name to create a new client workspace (agency admins, or agency
tokens with can_create_clients). It has no direct members: agency
people reach it through their agency role. Send workspace_id to bring
in a workspace you own directly.
| Parameter | In | Type | Description |
|---|
ag * | path | string, uuid | |
name | body | string | |
workspace_id | body | string, uuid | |
Responses: 201 The client workspace, 400 Error, 403 Error
delete/v1/agencies/{ag}/clients/{ws}
Take a workspace out of the agency
Signed in
Agency owners. The workspace and its data stay. If nobody owns it directly, you become its owner.
| Parameter | In | Type | Description |
|---|
ag * | path | string, uuid | |
ws * | path | string, uuid | |
Responses: 204 Removed, 404 Error
get/v1/agencies/{ag}/members
Agency members
Signed in
| Parameter | In | Type | Description |
|---|
ag * | path | string, uuid | |
Responses: 200 Members
post/v1/agencies/{ag}/members
Add someone who already has an account
Signed in
Agency admins. They get this role in every client workspace. Nobody can give a role above their own.
| Parameter | In | Type | Description |
|---|
ag * | path | string, uuid | |
email * | body | string | |
role * | body | "owner" | "admin" | "operator" | "viewer" | |
Responses: 200 Members, 404 Error
patch/v1/agencies/{ag}/members/{user}
Change an agency member's role
Signed in
| Parameter | In | Type | Description |
|---|
ag * | path | string, uuid | |
user * | path | string, uuid | |
role * | body | "owner" | "admin" | "operator" | "viewer" | |
Responses: 200 Members
delete/v1/agencies/{ag}/members/{user}
Remove someone from the agency
Signed in
The last owner can't be removed.
| Parameter | In | Type | Description |
|---|
ag * | path | string, uuid | |
user * | path | string, uuid | |
Responses: 204 Removed
get/v1/agencies/{ag}/api-tokens
Active agency tokens
Signed in
| Parameter | In | Type | Description |
|---|
ag * | path | string, uuid | |
Responses: 200 Tokens
post/v1/agencies/{ag}/api-tokens
Create a token that works in every client workspace
Signed in
Agency admins. Scopes apply in each client and can't exceed your agency role. The secret is returned once.
| Parameter | In | Type | Description |
|---|
ag * | path | string, uuid | |
name * | body | string | |
scopes * | body | "workspace.read" | "members.read" | "members.manage" | "tokens.manage" | "audit.read" | "mailboxes.read" | "mailboxes.manage" | "leads.read" | "leads.manage" | "suppressions.manage" | "sequences.read" | "sequences.manage" | "inbox.read" | "inbox.manage" | "integrations.read" | "integrations.manage" | "outcomes.read" | "outcomes.manage" | "projects.read" | "projects.manage" | "infrastructure.read" | "infrastructure.manage" | "infrastructure.approve" | "analytics.read" | "missions.read" | "missions.run" | "missions.approve"[] | |
can_create_clients | body | boolean | |
expires_in_days | body | integer | |
Responses: 201 Created
delete/v1/agencies/{ag}/api-tokens/{id}
Revoke an agency token
Signed in
| Parameter | In | Type | Description |
|---|
ag * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 204 Revoked
get/v1/agencies/{ag}/events
Agency log
Signed in
Agency admins. Clients, members, tokens and branding changes, newest first (last 200).
| Parameter | In | Type | Description |
|---|
ag * | path | string, uuid | |
Responses: 200 Events
Mailboxes
get/v1/workspaces/{ws}/mailboxes
List mailboxes
Scope: mailboxes.read.
Credentials are never returned.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
status | query | "verifying" | "active" | "paused" | "error" | |
stage | query | "warming" | "ready" | "resting" | "retired" | |
pool_id | query | string, uuid | |
domain | query | string | |
server_id | query | string, uuid | |
project_id | query | string | A project's id, or none for records shared by the workspace. A project token always sees only its project. |
Responses: 200 Mailboxes, ordered by email
post/v1/workspaces/{ws}/mailboxes
Add or update one mailbox
Scope: mailboxes.manage.
Upserts by email. Google Workspace and
Microsoft 365 are detected from MX records; other providers need the
host and port fields. The mailbox starts as verifying while a job
signs in over SMTP and IMAP.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
email * | body | string | |
display_name | body | string | |
provider | body | "google" | "microsoft" | "other" | |
password | body | string | App password used for both SMTP and IMAP. |
smtp_host | body | string | |
smtp_port | body | integer | |
smtp_username | body | string | |
smtp_password | body | string | |
imap_host | body | string | |
imap_port | body | integer | |
imap_username | body | string | |
imap_password | body | string | |
pool | body | string | Pool name. Created if missing. |
daily_limit | body | integer | |
Responses: 200 Updated an existing mailbox, 201 Added, 400 Error
post/v1/workspaces/{ws}/mailboxes/import
Bulk import mailboxes from CSV
Scope: mailboxes.manage. · Body: text/csv
Send the CSV file as the body (up to 5 MB and
5000 rows). Required columns: email and password (or
smtp_password). Optional: name (or first_name and last_name),
provider, smtp_host, smtp_port, smtp_username,
smtp_password, imap_host, imap_port, imap_username,
imap_password, pool and daily_limit. Common reseller and
sequencer headers such as Email Address and App Password are
recognised. Rows are upserted by email; bad rows are reported by line
and the rest still import.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
pool | query | string | Pool name for rows that do not name one. Created if missing. |
Responses: 200 Import summary, 400 Error, 413 Error, 415 Error
get/v1/workspaces/{ws}/mailboxes/{id}
Get a mailbox
Scope: mailboxes.read
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 200 The mailbox, 404 Error
patch/v1/workspaces/{ws}/mailboxes/{id}
Change a mailbox's name, limits, pool, or pause and resume it
Scope: mailboxes.manage.
Set status to paused to stop sending, or
to active to resume; resuming re-verifies the connection first.
Set pool_id to null to remove the mailbox from its pool.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
display_name | body | string | |
daily_limit | body | integer | |
min_gap_seconds | body | integer | |
pool_id | body | string, uuid | |
status | body | "paused" | "active" | |
warmup | body | object | Unset fields are left as they are. |
Responses: 200 The updated mailbox, 400 Error, 404 Error
delete/v1/workspaces/{ws}/mailboxes/{id}
Remove a mailbox and its stored credentials
Scope: mailboxes.manage
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 204 Removed, 404 Error
post/v1/workspaces/{ws}/mailboxes/{id}/verify
Re-check a mailbox's SMTP and IMAP sign-in and its domain's DNS
Scope: mailboxes.manage.
Runs in the background; poll the mailbox for the result.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 202 Queued, 404 Error
get/v1/workspaces/{ws}/mailboxes/{id}/warmup
A mailbox's warm-up results for each of the last 14 days
Scope: mailboxes.read.
Days are UTC, oldest first.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 200 Daily results, 404 Error
post/v1/workspaces/{ws}/mailboxes/warmup
Turn warm-up on or off, or change its settings, for many mailboxes
Scope: mailboxes.manage.
Applies to the mailboxes in mailbox_ids,
or to every mailbox in pool_id, or to every mailbox in the
workspace when neither is given. Warming mailboxes email each other,
so turn it on for at least two, ideally on different domains.
Turning warm-up on starts the ramp from its first day: 2 emails a
day, then 2 more each day up to daily_target.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 200 How many mailboxes changed, 400 Error
get/v1/workspaces/{ws}/mailbox-pools
List mailbox pools
Scope: mailboxes.read
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 200 Pools
post/v1/workspaces/{ws}/mailbox-pools
Create a mailbox pool
Scope: mailboxes.manage
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
name * | body | string | |
Responses: 201 Created, 409 Error
delete/v1/workspaces/{ws}/mailbox-pools/{id}
Delete a pool. Its mailboxes stay, without a pool.
Scope: mailboxes.manage
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 204 Deleted, 404 Error
get/v1/workspaces/{ws}/oauth-connections
List admin OAuth connections
Scope: mailboxes.read.
Secrets are never returned.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 200 Connections
post/v1/workspaces/{ws}/oauth-connections
Add a Google service account or a Microsoft Entra app
Scope: mailboxes.manage.
Admin-level access to every mailbox in an
organisation, so mailboxes can be added without passwords.
- Google: a service account key file with domain-wide delegation
for the scope https://mail.google.com/.
- Microsoft: an Entra app with the Exchange Online application
permissions IMAP.AccessAsApp and SMTP.SendAsApp. The secret is
checked by getting a token before it is saved.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
provider * | body | "google" | "microsoft" | |
name | body | string | Defaults to the service account's email or the tenant id. |
service_account | body | | Google: the key file, as a JSON object or as its text. |
tenant_id | body | string | Microsoft: directory (tenant) id. |
client_id | body | string | Microsoft: application (client) id. |
client_secret | body | string | Microsoft: client secret value. |
Responses: 201 Created, 400 Error
delete/v1/workspaces/{ws}/oauth-connections/{id}
Remove an OAuth connection
Scope: mailboxes.manage.
Refused with 409 while mailboxes use it.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 204 Removed, 404 Error, 409 Error
post/v1/workspaces/{ws}/oauth-connections/{id}/mailboxes
Add mailboxes that sign in through a connection
Scope: mailboxes.manage.
Up to 5000 at once. No passwords: each
mailbox signs in to SMTP and IMAP with XOAUTH2 using a token from
the connection. Mailboxes that already exist are switched to the
connection. Each is verified in the background.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
mailboxes * | body | object[] | |
pool | body | string | Pool name. Created if missing. |
daily_limit | body | integer | |
Responses: 200 Result. Errors refer to positions in the list, from 1, 400 Error, 404 Error
get/v1/workspaces/{ws}/oauth/{provider}/authorize
Connect one mailbox through the provider's consent screen
Scope: mailboxes.manage
, signed-in users only (not API tokens).
Open this in the browser: it redirects to Google or Microsoft, and
after approval back to /v1/oauth/callback, which adds the mailbox
and redirects to the web app with ?connected=<email> or
?oauth_error=<reason>. Needs the server's OAuth app to be
configured; see oauth_providers in /v1/meta.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
provider * | path | "google" | "microsoft" | |
pool | query | string | Pool for the connected mailbox. |
Responses: 302 Redirect to the consent screen, 400 Error, 403 Error
get/v1/oauth/callback
Where the provider returns after the consent screen
Public
Not called directly. Checks the signed state and that the same user is signed in.
| Parameter | In | Type | Description |
|---|
state * | query | string | |
code | query | string | |
error | query | string | |
Responses: 302 Redirect to the web app with the outcome
get/v1/workspaces/{ws}/integrations/{id}/mailboxes
List the mailboxes held at a supplier
Scope: mailboxes.read.
Every mailbox the connected supplier account
holds, imported or not, as of the last sync (every 15 minutes, and
at once on the supplier's webhooks). The first call for an
integration connected before syncing existed starts its first sync;
synced is false until it finishes.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | A mailbox supplier integration, such as Cheap Inboxes. |
import_state | query | "available" | "queued" | "waiting" | "app_password" | "imported" | "failed" | |
status | query | "provisioning" | "active" | "cancelling" | "cancelled" | "failed" | Status at the supplier. |
q | query | string | Part of the email address. |
limit | query | integer | |
offset | query | integer | |
Responses: 200 Mailboxes and counts, 404 Error, 422 Error
post/v1/workspaces/{ws}/integrations/{id}/mailboxes/sync
Refresh the supplier's mailboxes now
Scope: mailboxes.manage.
Queues a full sync. Mailboxes the supplier cancelled are paused in Outflare.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 202 Queued, 404 Error
post/v1/workspaces/{ws}/integrations/{id}/mailboxes/import
Import mailboxes from a supplier
Scope: mailboxes.manage.
Reads each mailbox's password from the
supplier and adds it like a CSV import, with SMTP, IMAP and DNS
checks in the background. Google mailboxes first get an app
password from the supplier (Google refuses plain passwords), at the
pace the supplier allows: Cheap Inboxes makes 20 an hour, so a large
Google import takes hours; follow import_state in the list.
Mailboxes still being set up wait and import when they turn active.
Listed mailboxes are imported again even if they were before, which
refreshes their passwords.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
all | body | boolean | Every mailbox not imported yet. |
external_ids | body | string[] | |
emails | body | string[] | |
Responses: 202 Queued, 400 Error, 404 Error
get/v1/workspaces/{ws}/emailbison-compat/calls
List calls made to the EmailBison-compatible API
Scope: mailboxes.read.
Outflare answers a subset of the EmailBison API
at /emailbison/{ws}/api/... so a mailbox supplier that pushes to a
self-hosted EmailBison (Cheap Inboxes does) can push into Outflare.
Authenticate with an Outflare API token as the EmailBison API key; a
write needs mailboxes.manage. Supported: GET users, GET
sender-emails (page, per_page, search), GET sender-emails/{id or
email}, POST sender-emails/imap-smtp, POST sender-emails/bulk,
PATCH sender-emails/{id}, DELETE sender-emails/{id} (pauses the
mailbox), PATCH warmup/sender-emails/enable|disable. Every call is
logged here, newest first, with field names but never values, so
any endpoint a client needs that Outflare does not answer yet shows
up as supported: false. The latest 1,000 per workspace are kept.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
limit | query | integer | |
Responses: 200 Calls, newest first, 401 Error, 403 Error
get/v1/workspaces/{ws}/integrations/{id}/mailbox-sync
How a supplier's mailboxes are synced
Scope: mailboxes.read.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 200 Settings, 404 Error
patch/v1/workspaces/{ws}/integrations/{id}/mailbox-sync
Change how a supplier's mailboxes are synced
Scope: mailboxes.manage.
Turning on auto_import queues every active mailbox not imported yet, and imports new ones as they appear.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
auto_import | body | boolean | |
app_passwords | body | boolean | Ask the supplier for Google app passwords before importing Google mailboxes. On by default. |
daily_limit | body | integer | Daily cap for imported mailboxes. Null uses the supplier's cap. |
Responses: 200 Settings, 400 Error, 404 Error
post/v1/integrations/{id}/webhook
Where a supplier posts its events
Public
Not called directly. Registered at the supplier when the engine's
PUBLIC_URL is https. The body's HMAC-SHA256 signature, keyed with the
secret the supplier issued, is checked; repeated deliveries are
ignored.
| Parameter | In | Type | Description |
|---|
id * | path | string, uuid | |
Responses: 200 Accepted, 401 Error, 404 Error
get/v1/workspaces/{ws}/mailbox-health
How every sending mailbox is doing
Scope: mailboxes.read.
Graded from every signal: sign-in and inbox sync
errors (explained, e.g. suspended account or revoked consent), send
failures, bounce rate, warm-up inbox placement, the domain's SPF, DKIM,
DMARC and blocklists, and new mailboxes not warming up. Each signal
says what to do. Worst first. Computed on read.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
level | query | "ok" | "warning" | "critical" | "paused" | |
mailbox_id | query | string | One or more ids |
Responses: 200 Health by mailbox, 400 Error
get/v1/workspaces/{ws}/mailbox-health/settings
Automatic pausing settings
Scope: mailboxes.read.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 200 The settings
put/v1/workspaces/{ws}/mailbox-health/settings
Change automatic pausing
Scope: mailboxes.manage.
Every field is optional.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
auto_pause | body | boolean | |
pause_bounce_rate | body | number | |
min_sends | body | integer | |
Responses: 200 The settings, 400 Error
Sending domains
get/v1/workspaces/{ws}/sending-domains
List sending domains with health, settings and sending stats
Scope: mailboxes.read.
Every domain your mailboxes send from, plus
domains added by hand. Each carries its DNS (MX, SPF, DKIM, DMARC)
and blocklist results, the issues to fix, its settings, mailbox
counts and sends, replies and bounces over rolling windows.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
project_id | query | string | A project's id, or none for records shared by the workspace. A project token always sees only its project. |
Responses: 200 Domains, sorted by name
post/v1/workspaces/{ws}/sending-domains
Add a domain to track before it has mailboxes
Scope: mailboxes.manage.
Accepts acme.com, @acme.com, a URL or an
address on the domain. Its DNS check runs in the background; poll the
domain until checked_at is set. Domains of connected mailboxes are
added on their own.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
domain * | body | string | |
Responses: 201 Added, 400 Error, 409 Error
post/v1/workspaces/{ws}/sending-domains/check
Re-check DNS and blocklists for every domain
Scope: mailboxes.manage.
Runs in the background. Every domain is also re-checked on its own once a day.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 202 Queued
get/v1/workspaces/{ws}/sending-domains/{domain}
Get a domain, with daily sends, replies and bounces for 14 days
Scope: mailboxes.read.
List the domain's mailboxes with GET /mailboxes?domain=.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
domain * | path | string | |
Responses: 200 The domain, 404 Error
patch/v1/workspaces/{ws}/sending-domains/{domain}
Pause or resume a domain, cap its daily sends, or set limits on all its mailboxes
Scope: mailboxes.manage.
status: paused stops sequence and test
sends from every mailbox on the domain (replies written in the inbox
still go); active resumes. daily_limit caps sends from all of the
domain's mailboxes together in any 24 hours; null removes the cap.
mailbox_daily_limit and mailbox_min_gap_seconds set those
settings on every mailbox on the domain at once.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
domain * | path | string | |
status | body | "active" | "paused" | |
daily_limit | body | integer | |
notes | body | string | |
mailbox_daily_limit | body | integer | |
mailbox_min_gap_seconds | body | integer | |
Responses: 200 The updated domain, 400 Error, 404 Error
delete/v1/workspaces/{ws}/sending-domains/{domain}
Stop tracking a domain that has no mailboxes
Scope: mailboxes.manage.
Returns 409 while mailboxes on the domain are connected.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
domain * | path | string | |
Responses: 204 Removed, 404 Error, 409 Error
post/v1/workspaces/{ws}/sending-domains/{domain}/check
Re-check a domain's DNS and blocklists now
Scope: mailboxes.manage.
Runs in the background; poll the domain for a new checked_at. Use it after changing DNS records.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
domain * | path | string | |
Responses: 202 Queued, 404 Error
servers
get/v1/workspaces/{ws}/sending-servers
List sending servers with IPs, blocklist results, settings and sending stats
Scope: mailboxes.read.
A sending server is the SMTP host a group of
mailboxes signs in to, and the IP addresses they share: a cold-email
SMTP vendor's server (Mailreef, Infraforge) or your own mail server.
Mailboxes outside Google and Microsoft join one on their own when
they are connected, grouped by smtp_host. Each server carries its
IPs, their blocklist results, the issues to fix, a shared daily
limit and pause, mailbox counts and sends over rolling windows.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 200 Servers, sorted by host
post/v1/workspaces/{ws}/sending-servers/check
Re-check IPs and blocklists for every server
Scope: mailboxes.manage.
Runs in the background. Every server is also re-checked on its own once a day.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 202 Queued
get/v1/workspaces/{ws}/sending-servers/{id}
Get a sending server
Scope: mailboxes.read.
List its mailboxes with GET /mailboxes?server_id=.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 200 The server, 404 Error
patch/v1/workspaces/{ws}/sending-servers/{id}
Pause or resume a server, cap its daily sends, or set its sending IPs
Scope: mailboxes.manage.
status: paused stops sequence and test
sends from every mailbox on the server (replies written in the inbox
still go); active resumes, including after an automatic blocklist
pause. daily_limit caps sends from all its mailboxes together in
any 24 hours; null removes the cap. pause_on_listing (on by
default) pauses the server when a check finds one of its IPs on a
blocklist, and resumes it when every IP is clear again; a pause by a
person is never lifted automatically. ips sets the sending
addresses by hand, for servers that accept mail on one address and
send from others; null goes back to the host's DNS records. Changing
ips queues a new check.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
name | body | string | |
status | body | "active" | "paused" | |
daily_limit | body | integer | |
notes | body | string | |
pause_on_listing | body | boolean | |
ips | body | string[] | |
Responses: 200 The updated server, 400 Error, 404 Error
delete/v1/workspaces/{ws}/sending-servers/{id}
Remove a server that no mailbox uses
Scope: mailboxes.manage.
Returns 409 while mailboxes still sign in to it.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 204 Removed, 404 Error, 409 Error
post/v1/workspaces/{ws}/sending-servers/{id}/check
Re-check a server's IPs and blocklists now
Scope: mailboxes.manage.
Runs in the background; poll the server for a new checked_at. Use it after a delisting request.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 202 Queued, 404 Error
tracking
get/v1/workspaces/{ws}/tracking-domains
List tracking domains
Scope: mailboxes.read.
Optional. Once a domain is verified, the
workspace's unsubscribe links and any click-tracked links use it
instead of this server's address. target is what the CNAME must
point to.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 200 Tracking domains
post/v1/workspaces/{ws}/tracking-domains
Add a tracking domain
Scope: mailboxes.manage.
Add a CNAME record from the domain to target first or after; the DNS is checked straight away and whenever you call check.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
domain * | body | string | |
Responses: 201 The domain, with the result of the first check, 400 Error, 409 Error
delete/v1/workspaces/{ws}/tracking-domains/{id}
Remove a tracking domain
Scope: mailboxes.manage.
Links already sent keep working only while the domain still points here.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 204 Removed, 404 Error
post/v1/workspaces/{ws}/tracking-domains/{id}/check
Check a tracking domain's DNS now
Scope: mailboxes.manage.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 200 The domain, with the result of the check, 404 Error
Leads
get/v1/workspaces/{ws}/leads
List and search leads, ordered by email
Scope: leads.read
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
list_id | query | string, uuid | |
q | query | string | Matches email, name or company. |
suppressed | query | boolean | |
verification | query | "deliverable" | "undeliverable" | "risky" | "unknown" | "unverified" | Latest verification result, or unverified for never checked. |
limit | query | integer | |
after | query | string | next_after from the previous page. |
Responses: 200 Leads
post/v1/workspaces/{ws}/leads
Add a lead, or update the lead with this email
Scope: leads.manage.
Empty fields keep stored values; custom fields are merged.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
email * | body | string | |
first_name | body | string | |
last_name | body | string | |
company | body | string | |
title | body | string | |
phone | body | string | |
linkedin_url | body | string | |
website | body | string | |
custom | body | object | |
list_id | body | string, uuid | |
Responses: 200 Updated, 201 Created, 400 Error
post/v1/workspaces/{ws}/leads/import
Bulk import leads from CSV
Scope: leads.manage. · Body: text/csv
Send the CSV file as the body (up to 50 MB and
100,000 rows). Only an email column is required. Standard columns are
recognised under common export names (first name, last name, full
name, company, title, phone, LinkedIn URL, website); every other
column is kept as a custom field under its snake_case header, for use
in templates. Leads are upserted by email: a row for an existing lead
fills in non-empty fields and merges custom fields. Rows repeating an
email within the file are merged. Suppressed people are imported but
counted, and are never emailed.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
list | query | string | Add every imported lead to this list, created if missing. |
Responses: 200 Import summary, 400 Error, 413 Error, 415 Error
get/v1/workspaces/{ws}/leads/{id}
Get a lead
Scope: leads.read
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 200 The lead, 404 Error
patch/v1/workspaces/{ws}/leads/{id}
Change a lead's fields
Scope: leads.manage.
In custom, a null value removes that field.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
first_name | body | string | |
last_name | body | string | |
company | body | string | |
title | body | string | |
phone | body | string | |
linkedin_url | body | string | |
website | body | string | |
custom | body | object | |
Responses: 200 The updated lead, 404 Error
delete/v1/workspaces/{ws}/leads/{id}
Delete a lead
Scope: leads.manage.
With suppress=true the address is also added to
the suppression list (reason do_not_contact), so an erasure request is
honoured even if the person is imported again later.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
suppress | query | boolean | |
Responses: 204 Deleted, 404 Error
get/v1/workspaces/{ws}/leads/{id}/sources
Where a lead's data came from
Scope: leads.read.
The providers that supplied this lead, their id for the person, and the list run that added it.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 200 Sources, 404 Error
Lead lists and data providers
get/v1/workspaces/{ws}/lead-lists
List lead lists, with each list's latest run
Scope: leads.read.
A project token sees only its project's lists.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
project_id | query | string | A project's id, or none for lists shared by the whole workspace. |
kind | query | "manual" | "search" | |
Responses: 200 Lists
post/v1/workspaces/{ws}/lead-lists
Create a lead list, optionally built from a data provider search
Scope: leads.manage.
A list with search_integration_id and filters is a search list that can be built and refreshed from that provider. Set build to true to queue the first build in the same call. A project token's lists always belong to its project.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 201 Created, 400 Error, 409 Error
post/v1/workspaces/{ws}/lead-lists/preview
Preview a search before building a list from it
Scope: leads.manage.
Queues a run that fetches one page (10 people) from the provider and saves nothing. Poll GET /list-runs/{run} for the sample and the total number of matches. No emails are revealed; some providers (People Data Labs) charge for search results.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
search_integration_id * | body | string, uuid | |
filters * | body | object | A people search in shared terms. Each field lists alternatives (any may match); fields combine (all must match). GET /data-providers says which filters each provider understands. |
project_id | body | string, uuid | Score the sample against this project's ICP. |
Responses: 202 Queued, 400 Error
get/v1/workspaces/{ws}/lead-lists/{id}
Get a lead list and its latest run
Scope: leads.read
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 200 The list, 404 Error
patch/v1/workspaces/{ws}/lead-lists/{id}
Change a list's settings
Scope: leads.manage.
Absent fields keep their value; filters are replaced as a whole.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
name | body | string | |
description | body | string | |
project_id | body | string, uuid | Null shares the list with the whole workspace. |
search_integration_id | body | string, uuid | The connected provider that searches. Null makes a manual list. |
filters | body | object | A people search in shared terms. Each field lists alternatives (any may match); fields combine (all must match). GET /data-providers says which filters each provider understands. |
enrich_integration_ids | body | string, uuid[] | Providers that find missing emails, tried in order until one answers. Empty uses the search provider if it can. |
max_leads | body | integer | Most new leads one run adds. Default 500. |
credit_cap | body | number | Most provider credits one run spends. Null for no cap. |
verify | body | boolean | Verify new addresses and leave out ones the workspace's verification settings block. Default true. |
verified_emails_only | body | boolean | Only add addresses the provider itself verified. Default false. |
skip_contacted_days | body | integer | Leave out people any sequence emailed in this many days. 0 turns it off. Default 90. |
skip_in_sequences | body | boolean | Leave out people active in another sequence. Default true. |
min_score | body | integer | Leave out people whose ICP fit is below this, before spending credits. Default 0. |
refresh_every_days | body | integer | Refresh on a schedule. Null refreshes only when asked. |
Responses: 200 The list, 400 Error, 404 Error
delete/v1/workspaces/{ws}/lead-lists/{id}
Delete a list. Its leads stay.
Scope: leads.manage
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 204 Deleted, 404 Error
get/v1/workspaces/{ws}/lead-lists/{id}/members
List a list's leads with their ICP fit scores
Scope: leads.read.
Sorted by score, best first, unless sort says otherwise.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
sort | query | "score" | "added" | "email" | |
q | query | string | Search email, name, company and title. |
min_score | query | integer | |
limit | query | integer | |
offset | query | integer | |
Responses: 200 Members, 404 Error
post/v1/workspaces/{ws}/lead-lists/{id}/leads
Add leads to a list
Scope: leads.manage.
Ids of leads outside the workspace are ignored.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
lead_ids * | body | string, uuid[] | |
Responses: 200 How many were added, 404 Error
delete/v1/workspaces/{ws}/lead-lists/{id}/leads/{lead}
Remove a lead from a list
Scope: leads.manage
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
lead * | path | string, uuid | |
Responses: 204 Removed, 404 Error
get/v1/workspaces/{ws}/lead-lists/{id}/runs
List a list's runs, newest first
Scope: leads.read
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 200 Runs, 404 Error
post/v1/workspaces/{ws}/lead-lists/{id}/runs
Build, refresh or enrich a list
Scope: leads.manage.
Spends provider credits. build and refresh search the provider, find missing emails through the waterfall and add new leads; enrich fills in missing fields on the list's leads. One run at a time per list (409 while one is queued or running). max_leads and credit_cap override the list's limits for this run only.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
kind | body | "build" | "refresh" | "enrich" | |
max_leads | body | integer | |
credit_cap | body | number | |
Responses: 202 Queued, 400 Error, 404 Error, 409 Error
get/v1/workspaces/{ws}/list-runs/{run}
Get a run's progress or result
Scope: leads.read
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
run * | path | string, uuid | |
Responses: 200 The run, 404 Error
post/v1/workspaces/{ws}/list-runs/{run}/cancel
Stop a queued or running run. Leads already added stay.
Scope: leads.manage
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
run * | path | string, uuid | |
Responses: 200 The run, 404 Error, 409 Error
get/v1/workspaces/{ws}/data-providers
Data providers that can search for people, find emails or enrich
Scope: leads.read.
Every data connector, available or planned, with the workspace's connected accounts for each and the filters its search understands. Connect one with POST /integrations.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 200 Providers and the shared filter vocabulary
Suppression
get/v1/workspaces/{ws}/suppressions
List the suppression list, ordered by value
Scope: leads.read
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
kind | query | "email" | "domain" | |
reason | query | "unsubscribed" | "bounced" | "complained" | "manual" | "do_not_contact" | |
q | query | string | |
limit | query | integer | |
after | query | string | next_after from the previous page. |
Responses: 200 Entries
post/v1/workspaces/{ws}/suppressions
Add emails or domains to the suppression list
Scope: leads.manage.
Each value is an email address or a domain
(also accepted as @acme.com or a URL). A suppressed domain blocks
every address at it. Existing entries are left as they are.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
values * | body | string[] | |
reason | body | "unsubscribed" | "bounced" | "complained" | "manual" | "do_not_contact" | |
note | body | string | |
Responses: 200 Result, 400 Error
delete/v1/workspaces/{ws}/suppressions/{id}
Remove a suppression entry
Scope: suppressions.manage
(owners and admins by default). Audited.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 204 Removed, 404 Error
post/v1/workspaces/{ws}/recipients/check
Ask the send policy whether addresses may be emailed
Scope: leads.read.
Runs the same recipient checks every send goes
through, without sending. Use it to filter before enrolling leads.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
emails * | body | string[] | |
Responses: 200 One decision per email, in order
Sequences
post/v1/workspaces/{ws}/mailboxes/{id}/test-send
Send one test email from a mailbox now
Scope: mailboxes.manage.
Goes through the recipient check and the
mailbox's status, daily limit and minimum gap (not the sending
window) and counts towards the daily limit. Returns 409 when the
policy blocks it and 502 when the SMTP server refuses it.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
to * | body | string, email | |
subject | body | string | |
body | body | string | |
Responses: 200 Sent, 400 Error, 404 Error, 409 Error, 502 Error
get/v1/workspaces/{ws}/sequences
List sequences (archived ones are left out)
Scope: sequences.read
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
project_id | query | string | A project's id, or none for records shared by the workspace. A project token always sees only its project. |
Responses: 200 Sequences, newest first, with steps and enrollment counts
post/v1/workspaces/{ws}/sequences
Create a sequence
Scope: sequences.manage.
A new sequence is a draft: it sends
nothing until its status is set to active. Defaults: UTC,
Monday to Friday, 09:00 to 17:00, no daily cap on new leads, stop on
reply.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 201 The sequence, 400 Error
get/v1/workspaces/{ws}/sequences/{id}
Get a sequence
Scope: sequences.read
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 200 The sequence, 404 Error
patch/v1/workspaces/{ws}/sequences/{id}
Change a sequence's settings, or activate, pause or archive it
Scope: sequences.manage.
Activating needs at least one step, and a
daily_new_limit or target_daily (or mailboxes assigned by hand) so
Outflare knows how many mailboxes to allocate; it allocates them
straight away. Pausing holds every enrollment where it is, keeps the
mailboxes with leads mid-sequence and frees the rest; activating
again carries on.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 200 The updated sequence, 400 Error, 404 Error
delete/v1/workspaces/{ws}/sequences/{id}
Delete a sequence that is not active
Scope: sequences.manage.
Sent messages are kept in the message log.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 204 Deleted, 400 Error, 404 Error
put/v1/workspaces/{ws}/sequences/{id}/steps
Replace a sequence's steps
Scope: sequences.manage.
The first step needs a subject. A later
step with an empty subject replies in the same thread ("Re: ...").
delay_days is the wait after the previous step (at least 1 after
the first). Enrollments carry on from their current position.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
steps * | body | object[] | |
Responses: 200 The sequence, 400 Error, 404 Error
post/v1/workspaces/{ws}/sequences/{id}/preview
Render every step for one lead
Scope: sequences.read.
Shows the subject and body each step would
send, and any variables the lead is missing (a missing variable
blocks the real send).
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
lead_id * | body | string, uuid | |
Responses: 200 Rendered steps, 404 Error
get/v1/workspaces/{ws}/sequences/{id}/enrollments
List the leads in a sequence, ordered by email
Scope: sequences.read
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
status | query | "active" | "completed" | "stopped" | "unsubscribed" | "bounced" | "replied" | "blocked" | "failed" | |
limit | query | integer | |
after | query | string | next_after from the previous page. |
Responses: 200 Enrollments
post/v1/workspaces/{ws}/sequences/{id}/enrollments
Add leads to a sequence
Scope: sequences.manage.
Send lead_ids or list_id. Suppressed
leads are skipped, and so are leads active in another sequence
unless skip_active_elsewhere is false. Adding a lead twice does
nothing.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
lead_ids | body | string, uuid[] | |
list_id | body | string, uuid | |
skip_active_elsewhere | body | boolean | |
Responses: 200 Counts, 400 Error, 404 Error
post/v1/workspaces/{ws}/sequences/{id}/enrollments/{eid}/stop
Stop sending to one lead in a sequence
Scope: sequences.manage
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
eid * | path | string, uuid | |
Responses: 204 Stopped, 404 Error
get/v1/workspaces/{ws}/messages
List sent, failed and blocked messages, newest first
Scope: sequences.read.
Every send attempt is recorded, including the
ones the policy blocked and why.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
sequence_id | query | string, uuid | |
lead_id | query | string, uuid | |
mailbox_id | query | string, uuid | |
enrollment_id | query | string, uuid | |
status | query | "sending" | "sent" | "failed" | "blocked" | "unknown" | |
limit | query | integer | |
before | query | string, date-time | next_before from the previous page. |
Responses: 200 Messages
get/u/{token}
Unsubscribe page linked from every email
Public
Shows a confirmation button. A GET never unsubscribes, because mail
scanners follow links.
| Parameter | In | Type | Description |
|---|
token * | path | string | |
Responses: 200 HTML page, 404 The link is not valid
post/u/{token}
Unsubscribe (the page's button and RFC 8058 one-click)
Public
Adds the address to the suppression list (reason unsubscribed) and
stops every active sequence for it in the workspace.
| Parameter | In | Type | Description |
|---|
token * | path | string | |
Responses: 200 HTML confirmation, 404 The link is not valid
Inbox
post/v1/workspaces/{ws}/mailboxes/{id}/sync
Check a mailbox for new mail now
Scope: mailboxes.manage.
Active mailboxes are also synced automatically every two minutes.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 202 Sync queued, 404 Error, 409 Error
get/v1/workspaces/{ws}/inbox
List received mail, newest first
Scope: inbox.read.
By default only replies and auto-replies from
leads are listed; pass kind=all to include bounce reports and
other mail.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
kind | query | "reply" | "auto_reply" | "bounce" | "other" | "all" | |
unread | query | boolean | |
mailbox_id | query | string, uuid | |
lead_id | query | string, uuid | |
sequence_id | query | string, uuid | |
status | query | "open" | "snoozed" | "done" | "all" | open: not done and not snoozed. Default all. |
category | query | "interested" | "meeting_booked" | "question" | "referral" | "not_now" | "not_interested" | "wrong_person" | "out_of_office" | "unsubscribe" | "none" | A category, or none for replies nobody has sorted yet. |
assigned_to | query | string | me (signed-in person only), none, or a user id. |
label | query | string | |
q | query | string | Search sender and subject. |
limit | query | integer | |
before | query | string, date-time | next_before from the previous page. |
Responses: 200 Messages
get/v1/workspaces/{ws}/inbox/{id}
Get a received message and its conversation
Scope: inbox.read.
thread holds everything sent to and received
from the lead through that mailbox, oldest first.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 200 The message and thread, 404 Error
patch/v1/workspaces/{ws}/inbox/{id}
Triage a message
Scope: inbox.manage.
Send only the fields to change. Mark it read,
sort it into a category, assign it to a member, snooze it, mark it
done or set its labels. Changes other than read are audited.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
read | body | boolean | |
category | body | "interested" | "meeting_booked" | "question" | "referral" | "not_now" | "not_interested" | "wrong_person" | "out_of_office" | "unsubscribe" | |
assigned_to | body | string, uuid | A workspace member's user id |
snoozed_until | body | string, date-time | Must be in the future; null wakes it now. |
done | body | boolean | |
labels | body | string[] | Replaces the labels. Lower-cased. |
Responses: 200 The message, 404 Error
post/v1/workspaces/{ws}/inbox/{id}/reply
Reply from the mailbox the message arrived at, in the same thread
Scope: inbox.manage.
Goes through the recipient check (a suppressed
or opted-out address gets 409) and needs the mailbox to be active.
It is not held to a sequence's sending window or the mailbox's
pacing, but counts towards its daily limit.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
body * | body | string | |
Responses: 200 Sent, 400 Error, 404 Error, 409 Error, 502 Error
connectors
get/v1/connectors
Every connector this server ships, available or planned
Public
Public, no key needed. Each entry says what the connector is, how it
signs in (api_key, oauth2 or none), the fields to paste, and its
capabilities. configured is false for OAuth connectors whose app is
not set up on this server.
Responses: 200 The catalog, available first, then by category and name
get/v1/workspaces/{ws}/connectors
The catalog, with how many accounts the workspace connected to each
Scope: integrations.read.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
category | query | "email_verification" | "sequencer" | "mailbox_provider" | "dns" | "crm" | "data" | "signals" | "analytics" | "seo" | "calendar" | "registrar" | "warehouse" | "notification" | "model" | "custom" | |
Responses: 200 The catalog
get/v1/workspaces/{ws}/integrations
List connected accounts
Scope: integrations.read.
Credentials are never returned.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
connector | query | string | Only this connector id. |
category | query | "email_verification" | "sequencer" | "mailbox_provider" | "dns" | "crm" | "data" | "signals" | "analytics" | "seo" | "calendar" | "registrar" | "warehouse" | "notification" | "model" | "custom" | |
Responses: 200 Integrations, oldest first
post/v1/workspaces/{ws}/integrations
Connect an account with an API key
Scope: integrations.manage.
The credentials are tested against the
service before anything is saved, and refused with
connector_auth if wrong. OAuth connectors are connected through
GET /integrations/oauth/{connector}/authorize instead.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
connector * | body | string | |
name | body | string | Defaults to the connector's name, numbered if taken. |
credentials * | body | object | The connector's fields by name, e.g. {"api_key":"..."}. |
Responses: 201 Connected, 400 Error, 409 Error, 422 Error, 429 Error, 502 Error
get/v1/workspaces/{ws}/integrations/{id}
Get a connected account
Scope: integrations.read.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 200 The integration, 404 Error
patch/v1/workspaces/{ws}/integrations/{id}
Rename, replace the API key, or change settings
Scope: integrations.manage.
New credentials are tested before they replace the old ones.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
name | body | string | |
credentials | body | object | |
config | body | object | |
Responses: 200 Updated, 400 Error, 404 Error, 422 Error
delete/v1/workspaces/{ws}/integrations/{id}
Disconnect an account
Scope: integrations.manage.
Deletes the stored credentials. Features using it fall back (verification goes back to the built-in checks).
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 204 Disconnected, 404 Error
post/v1/workspaces/{ws}/integrations/{id}/test
Sign in again with the stored credentials
Scope: integrations.manage.
Reads the account (and credits, when the service reports them); changes nothing at the service and spends no credits.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 200 The integration with its status and last_error updated, 404 Error
get/v1/workspaces/{ws}/integrations/oauth/{connector}/authorize
Start connecting an OAuth connector
Scope: integrations.manage.
Redirects to the service's sign-in page;
afterwards the browser lands on the workspace's Connectors page.
With format=json it returns the link instead, for an agent to hand
to a person.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
connector * | path | string | |
name | query | string | |
format | query | "json" | |
Responses: 200 The sign-in link (format=json), 302 Redirect to the sign-in page, 400 Error, 404 Error
get/v1/integrations/oauth/callback
Where connector sign-in pages return to
Public
Not called directly. Redirects to the Connectors page with integration (the new integration id) or connect_error.
Responses: 302 Redirect to the web app
get/v1/workspaces/{ws}/connect-requests
List connect requests
Scope: integrations.read.
The 100 newest, with status pending, connected, cancelled or expired.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 200 Connect requests, newest first
post/v1/workspaces/{ws}/connect-requests
Ask a person to connect a service
Scope: integrations.manage.
The agent-first way to connect anything:
returns a one-time link to give the person. They open it, without
logging in, and paste the key or approve the OAuth sign-in. The
secret never passes through the agent. Poll
GET /connect-requests/{id} until status is connected.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
connector * | body | string | |
name | body | string | Name for the integration it creates. |
reason | body | string | Why it is needed; shown to the person on the link's page. |
use_for_verification | body | boolean | Make it the workspace's verification service. Default true for verification connectors. |
expires_in_minutes | body | integer | Default 1440 (24 hours). |
Responses: 201 Created. `url` is only returned here, 400 Error
get/v1/workspaces/{ws}/connect-requests/{id}
Read a connect request
Scope: integrations.read.
Once status is connected, integration_id is the new integration.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 200 The request, 404 Error
delete/v1/workspaces/{ws}/connect-requests/{id}
Cancel a pending connect request
Scope: integrations.manage.
The link stops working.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 204 Cancelled, 404 Error
post/v1/connect/lookup
What a connect link is for
Public
Used by the link's page. No login; the token from the link is the authority.
| Parameter | In | Type | Description |
|---|
token * | body | string | |
Responses: 200 The connector and who asked, 404 Error, 410 Error
post/v1/connect/complete
Finish a connect link with an API key
Public
Tests the credentials and saves the integration. The link then stops working.
| Parameter | In | Type | Description |
|---|
token * | body | string | |
credentials * | body | object | |
Responses: 201 Connected, 400 Error, 409 Error, 410 Error, 422 Error
post/v1/connect/oauth
Start the OAuth sign-in for a connect link
Public
| Parameter | In | Type | Description |
|---|
token * | body | string | |
Responses: 200 The provider's sign-in URL. Afterwards the browser lands on /connect, 400 Error, 410 Error
analytics
get/v1/workspaces/{ws}/analytics
List connected analytics tools
Scope: analytics.read.
Every connection that reads website or
product analytics or a search console (Google Analytics, Search
Console, Bing Webmaster Tools, PostHog, Plausible and the rest),
with the reports each one answers and its default site. Connect one
with POST .../integrations (API key) or the OAuth authorize link,
or hand a person a link with POST .../connect-requests. Nothing
needs to be connected for the rest of Outflare to work.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 200 The connections
get/v1/workspaces/{ws}/analytics/summary
Traffic totals from every analytics tool
Scope: analytics.read.
The traffic report's totals from every
analytics connection over one range, in one call. A connection
that fails (no site picked, revoked key) carries an error instead
of failing the answer. Dates are inclusive; the default is the
last 28 days.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
from | query | string, date | First day, inclusive (YYYY-MM-DD). Default 27 days before to. |
to | query | string, date | Last day, inclusive (YYYY-MM-DD). Default today (UTC). |
fresh | query | boolean | true skips the short cache and asks the provider again. |
Responses: 200 One entry per connection, 400 Error
get/v1/workspaces/{ws}/analytics/history
Query stored analytics history
Scope: analytics.read.
Reads what the sync stored, without calling the tools.
group is day (one row per day per tool; the default for traffic),
tool (totals per tool), key (each page, source, query or event added up
across the tools picked; the default for the other reports) or tool_key.
Counts are summed, click-through rate and position are weighted by impressions.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
report | query | "traffic" | "pages" | "sources" | "search_queries" | "events" | |
group | query | "day" | "tool" | "key" | "tool_key" | |
integration | query | string, uuid | Only this connection. |
host | query | string | Only this website. |
from | query | string, date | First day. Default 28 days before to. |
to | query | string, date | Last day. Default yesterday (UTC). |
limit | query | integer | |
Responses: 200 Stored rows, 400 Error
get/v1/workspaces/{ws}/analytics/overview
Every website across every tool
Scope: analytics.read.
Stored traffic totals per website (by domain), with each tool side by side, search clicks added up across search consoles, and every connection's sync status.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
from | query | string, date | |
to | query | string, date | |
Responses: 200 The overview, 400 Error
get/v1/workspaces/{ws}/analytics/changes
What changed on each website
Scope: analytics.read.
Reads stored data only, so it is free. For each website (by domain): each tool's metrics over its own latest days stored days against the same number of days before (so a tool that runs behind is not read as a drop), search clicks added up across search consoles, the pages, sources and search queries that rose or fell most, unusual days against the 28 days before, the latest SEO snapshot against the one before (with keyword moves), plain-sentence headlines, and gaps: what is missing and which connector or action fixes it. Units for every metric are given once, in units.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
days | query | integer | Period length, 1 to 90. Default 7. |
to | query | string, date | Last day to consider. Default yesterday, UTC. |
host | query | string | One website, like example.com. |
limit | query | integer | Movers, unusual days and keyword moves per list, 1 to 25. Default 5. |
Responses: 200 Changes per website, 400 Error
get/v1/workspaces/{ws}/analytics/catalog
What each website can be asked
Scope: analytics.read.
For each website: the analytics tools, which metrics each has stored per report, the days stored and last sync, the SEO tools with snapshots and budget left, and gaps with the connector or action that fixes each. ask maps common questions to the tool or endpoint that answers them.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 200 The catalog
get/v1/workspaces/{ws}/analytics/syncs
What the sync has stored for each connection
Scope: analytics.read.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 200 One entry per analytics connection
post/v1/workspaces/{ws}/analytics/sync
Sync every analytics connection soon
Scope: analytics.read.
Queues a sync of each connected tool. Syncs also run by themselves every six hours (daily for Clarity).
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 202 Queued, 503 Error
post/v1/workspaces/{ws}/analytics/{id}/sync
Sync one analytics connection now
Scope: analytics.read.
The first sync stores 90 days of traffic and 7 days of
pages, sources, search queries and events; later ones re-read the last three days.
Answers once it is done, with the rows stored and the calls made.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 200 Done, 400 Error, 404 Error, 422 Error
get/v1/workspaces/{ws}/analytics/{id}/sites
List the sites a connection can read
Scope: analytics.read.
GA4 properties, Search Console properties, PostHog projects, Fathom or Umami sites, and so on. Pass an id as site on reports, or make it the default.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | The integration id. |
fresh | query | boolean | true skips the short cache and asks the provider again. |
Responses: 200 The sites, and the current default, 404 Error, 422 Error
put/v1/workspaces/{ws}/analytics/{id}/site
Set a connection's default site
Scope: integrations.manage.
The site must be one the connection can read. An empty site clears the default.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
site * | body | string | |
domain | body | string | The website's domain, which lines this connection up with other tools in the overview and compare. Set it when the tool does not show one (Google Analytics properties, Vercel projects). An empty string clears it. Stored history moves to the new domain. |
Responses: 200 Saved, 400 Error, 404 Error
get/v1/workspaces/{ws}/analytics/{id}/reports/{report}
Read one analytics report
Scope: analytics.read.
The same report from any provider:
traffic (totals plus one point per day), pages, sources
(referrers), search_queries (Search Console and Bing) and
events (events and conversions). A metric a provider does not
measure is left out, never reported as zero. Read notes for
caveats such as data delay. Answers are kept for 15 minutes (an
hour for Mixpanel and Amplitude, six hours for Clarity) to spare
the provider's rate limits; fresh=true reads again.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
report * | path | "traffic" | "pages" | "sources" | "search_queries" | "events" | |
site | query | string | A site id from .../sites. Default: the connection's default site, or its only one. |
from | query | string, date | First day, inclusive (YYYY-MM-DD). Default 27 days before to. |
to | query | string, date | Last day, inclusive (YYYY-MM-DD). Default today (UTC). |
limit | query | integer | Rows in a breakdown report. |
fresh | query | boolean | true skips the short cache and asks the provider again. |
Responses: 200 The report, 400 Error, 404 Error, 422 Error, 429 Error, 502 Error
seo
get/v1/workspaces/{ws}/seo
List SEO connections
Scope: analytics.read.
DataForSEO and Ahrefs connections with their reports, the domains they follow, the country, the weekly snapshot setting and this month's budget and spend. Empty means none is connected; nothing else needs one.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 200 SEO connections
get/v1/workspaces/{ws}/seo/history
Read stored SEO snapshots
Scope: analytics.read.
Reads what the weekly snapshots stored, without
calling or paying the provider. overview gives one row per
connection, domain and snapshot day. keywords (and the other
lists) gives each connection's latest snapshot, with previous
holding the same keyword's numbers from the snapshot before, unless
from or to name a range.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
report | query | "overview" | "keywords" | "backlinks" | "competitors" | "audit" | |
host | query | string | |
integration | query | string, uuid | |
from | query | string, date | |
to | query | string, date | |
limit | query | integer | |
Responses: 200 Stored rows, newest first, 400 Error
put/v1/workspaces/{ws}/seo/{id}/settings
Set an SEO connection's domains, country, budget and snapshots
Scope: integrations.manage.
Send only what changes. domains: null follows the domains the analytics tools line up (at most five); monthly_budget: null is the default ($10 for DataForSEO, 10,000 API units for Ahrefs); 0 stops every call.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
domains | body | string[] | |
country | body | string | Two-letter code for keywords and traffic. |
monthly_budget | body | number | Per calendar month (UTC): US dollars for DataForSEO, API units for Ahrefs. |
sync | body | "weekly" | "off" | |
Responses: 200 The connection with its new settings, 400 Error, 404 Error
get/v1/workspaces/{ws}/seo/{id}/reports/{report}
Read one SEO report live (costs money)
Scope: analytics.read.
Asks the provider now, which costs money:
cost says what this answer cost and budget what is left this
month. A call that would go over the connection's monthly budget
answers 402 budget_reached without calling. Answers are kept for
a day, so asking again is free; fresh=true pays again. Every paid
call is recorded in Outcomes spend. Prefer GET .../seo/history for
anything the weekly snapshot already has.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
report * | path | "overview" | "keywords" | "backlinks" | "competitors" | "audit" | |
target | query | string | A domain. Default: the connection's only domain. |
country | query | string | |
limit | query | integer | |
fresh | query | boolean | |
Responses: 200 The report, 400 Error, 402 Error, 404 Error, 422 Error, 429 Error, 502 Error
post/v1/workspaces/{ws}/seo/{id}/sync
Take an SEO snapshot now
Scope: integrations.manage.
Stores the overview and top 50 keywords of every domain the connection follows, within its budget (this also runs weekly). Costs about $0.04 a domain on DataForSEO or 1,200 API units on Ahrefs.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 200 What was stored and what it cost, 400 Error, 402 Error, 422 Error, 503 Error
verification
get/v1/workspaces/{ws}/verification-settings
How the workspace verifies addresses
Scope: leads.read.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 200 The settings
put/v1/workspaces/{ws}/verification-settings
Choose the verification service and what to block
Scope: leads.manage.
Every field is optional. integration_id empty
or builtin switches to the free built-in checks. Undeliverable
addresses are always blocked.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
integration_id | body | string | |
verify_on_import | body | boolean | |
verify_before_send | body | boolean | |
block_risky | body | boolean | |
block_catch_all | body | boolean | |
block_unknown | body | boolean | |
max_age_days | body | integer | |
Responses: 200 Saved, 400 Error
get/v1/workspaces/{ws}/verifications
Verification results, newest first
Scope: leads.read.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
status | query | "deliverable" | "undeliverable" | "risky" | "unknown" | |
email | query | string | One or more addresses, comma-separated or repeated. |
limit | query | integer | |
Responses: 200 Results
post/v1/workspaces/{ws}/verifications
Verify addresses, a lead list, or every unverified lead
Scope: leads.manage.
Runs in the background; results appear under
GET /verifications. Addresses with a fresh result are skipped unless
force is true. Paid services spend credits.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
emails | body | string, email[] | |
list_id | body | string, uuid | |
unverified | body | boolean | Every lead without a fresh result. |
force | body | boolean | |
Responses: 202 Queued, 400 Error
get/v1/workspaces/{ws}/verifications/summary
Lead counts by verification status
Scope: leads.read.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 200 Counts
outcomes
get/v1/workspaces/{ws}/outcomes/report
Cost per reply, meeting and deal
Scope: outcomes.read.
Sends, replies, meetings, deals and spend over a
period, for the workspace or per project or sequence, with cost per
reply, per meeting, per held meeting and per deal. Spend tied to a
sequence, project, mailbox or domain is charged to it directly; the
rest is shared out by each row's share of emails sent. Usage recorded
only as units (credits) is priced with the workspace's spend rates and
reported as estimated; usage with no rate is listed under unpriced.
Nothing is converted between currencies.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
from | query | string | Start of the period, inclusive. A date (2026-10-01) or a time. Default 30 days before to. |
to | query | string | End of the period. A date includes that whole day. Default now. |
group_by | query | "none" | "project" | "sequence" | |
project_id | query | string, uuid | |
sequence_id | query | string, uuid | |
mission_id | query | string, uuid | Only meetings, deals and spend recorded for this mission. |
currency | query | string | |
Responses: 200 The report, 400 Error
get/v1/workspaces/{ws}/outcomes/export
Export meetings, deals, spend or the report
Scope: outcomes.read.
Rows for a warehouse or a spreadsheet, as CSV
(default) or newline-delimited JSON. Up to 100,000 rows per call;
narrow from and to for more. The report dataset takes the report's
query parameters and defaults to group_by=sequence.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
dataset * | query | "meetings" | "deals" | "spend" | "report" | |
format | query | "csv" | "ndjson" | |
from | query | string | Start of the period, inclusive. A date (2026-10-01) or a time. Default 30 days before to. |
to | query | string | End of the period. A date includes that whole day. Default now. |
group_by | query | "none" | "project" | "sequence" | |
currency | query | string | |
Responses: 200 The file, 400 Error
get/v1/workspaces/{ws}/outcomes/syncs
Calendar and CRM sync status
Scope: outcomes.read.
Every connected calendar, booking tool and CRM, with when each stream (meetings, deals, push) last ran, what it changed and its last error. Syncs run every 15 minutes.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 200 Sync status
post/v1/workspaces/{ws}/outcomes/syncs/{id}/run
Sync a calendar or CRM now
Scope: outcomes.manage.
Queues a sync instead of waiting for the next one.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | The integration id. |
Responses: 202 Queued, 400 Error, 404 Error
get/v1/workspaces/{ws}/meetings
List meetings with leads
Scope: outcomes.read.
Newest first. Page with before=next_before.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
from | query | string | Start of the period, inclusive. A date (2026-10-01) or a time. Default 30 days before to. |
to | query | string | End of the period. A date includes that whole day. Default now. |
project_id | query | string, uuid | |
sequence_id | query | string, uuid | |
mission_id | query | string, uuid | |
status | query | "booked" | "held" | "no_show" | "canceled" | |
attributed | query | boolean | Only meetings tied to outreach. |
limit | query | integer | |
before | query | string, date-time | |
Responses: 200 Meetings
post/v1/workspaces/{ws}/meetings
Log a meeting
Scope: outcomes.manage.
For meetings no connected calendar sees. Give
lead_id or attendee_email; the meeting is tied to the sequence that
last emailed that lead, unless sequence_id or project_id is given
(which pins it). Status defaults to held for a meeting more than an
hour in the past, otherwise booked.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
lead_id | body | string, uuid | |
attendee_email | body | string | |
attendee_name | body | string | |
sequence_id | body | string, uuid | |
project_id | body | string, uuid | |
mission_id | body | string, uuid | |
title | body | string | |
starts_at * | body | string, date-time | |
ends_at | body | string, date-time | |
booked_at | body | string, date-time | Default now. Decides which sequence gets the credit. |
status | body | "booked" | "held" | "no_show" | "canceled" | |
qualified | body | boolean | |
notes | body | string | |
external_id | body | string | |
Responses: 201 The meeting, 400 Error
get/v1/workspaces/{ws}/meetings/{id}
Get a meeting
Scope: outcomes.read.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 200 The meeting, 404 Error
patch/v1/workspaces/{ws}/meetings/{id}
Mark a meeting held, no-show or qualified, or fix its attribution
Scope: outcomes.manage.
Setting sequence_id, project_id or
unattributed pins the attribution so syncs never move it. A status a
person sets (held, no_show) is kept by syncs, unless the source
cancels the meeting.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
status | body | "booked" | "held" | "no_show" | "canceled" | |
qualified | body | boolean | |
notes | body | string | |
title | body | string | |
starts_at | body | string, date-time | |
sequence_id | body | string, uuid | |
project_id | body | string, uuid | |
mission_id | body | string | An id |
unattributed | body | boolean | Not from outreach; pins that. |
Responses: 200 The meeting, 400 Error, 404 Error
delete/v1/workspaces/{ws}/meetings/{id}
Delete a meeting
Scope: outcomes.manage.
A synced meeting comes back on the next sync; mark it canceled or unattributed instead.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 204 Deleted, 404 Error
get/v1/workspaces/{ws}/deals
List deals
Scope: outcomes.read.
Deals from the CRM, plus any logged by hand. Newest first.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
from | query | string | Start of the period, inclusive. A date (2026-10-01) or a time. Default 30 days before to. |
to | query | string | End of the period. A date includes that whole day. Default now. |
project_id | query | string, uuid | |
sequence_id | query | string, uuid | |
mission_id | query | string, uuid | |
state | query | "open" | "won" | "lost" | |
attributed | query | boolean | |
limit | query | integer | |
before | query | string, date-time | |
Responses: 200 Deals
post/v1/workspaces/{ws}/deals
Log a deal
Scope: outcomes.manage.
For workspaces without a connected CRM. Give meeting_id, lead_id or contact_email to tie it to outreach.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
name * | body | string | |
lead_id | body | string, uuid | |
contact_email | body | string | |
meeting_id | body | string, uuid | |
sequence_id | body | string, uuid | |
project_id | body | string, uuid | |
mission_id | body | string, uuid | |
stage | body | string | |
state | body | "open" | "won" | "lost" | Default open. |
amount_cents | body | integer | |
currency | body | string | Default USD. |
opened_at | body | string, date-time | |
closed_at | body | string, date-time | |
external_id | body | string | |
Responses: 201 The deal, 400 Error
get/v1/workspaces/{ws}/deals/{id}
Get a deal
Scope: outcomes.read.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 200 The deal, 404 Error
patch/v1/workspaces/{ws}/deals/{id}
Change a deal or its attribution
Scope: outcomes.manage.
A deal synced from a CRM only takes attribution changes here; change its name, stage or amount in the CRM.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
name | body | string | |
stage | body | string | |
state | body | "open" | "won" | "lost" | |
amount_cents | body | integer | |
currency | body | string | |
closed_at | body | string, date-time | |
sequence_id | body | string, uuid | |
project_id | body | string, uuid | |
mission_id | body | string | |
unattributed | body | boolean | |
Responses: 200 The deal, 400 Error, 404 Error
delete/v1/workspaces/{ws}/deals/{id}
Delete a deal
Scope: outcomes.manage.
Removes the copy here only; the CRM is not touched.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 204 Deleted, 404 Error
get/v1/workspaces/{ws}/spend
List the spend ledger
Scope: outcomes.read.
One-off charges, newest first. The ledger records cost; it never bills. Providers are paid directly.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
from | query | string | Start of the period, inclusive. A date (2026-10-01) or a time. Default 30 days before to. |
to | query | string | End of the period. A date includes that whole day. Default now. |
project_id | query | string, uuid | |
sequence_id | query | string, uuid | |
mission_id | query | string, uuid | |
category | query | "data" | "verification" | "mailboxes" | "domains" | "sending" | "software" | "people" | "ads" | "other" | |
provider | query | string | |
limit | query | integer | |
before | query | string, date-time | |
Responses: 200 Entries
post/v1/workspaces/{ws}/spend
Record spend
Scope: outcomes.manage.
Give amount_cents when the money is known, or
units with a unit_name (e.g. 1200 credit) to have reports price it
with the workspace's rates. With a ref already in the ledger nothing
is added and the existing entry comes back with 200, so retries never
double count. project_id is filled from the sequence, mailbox or
domain when left out.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
category * | body | "data" | "verification" | "mailboxes" | "domains" | "sending" | "software" | "people" | "ads" | "other" | |
provider | body | string | |
amount_cents | body | integer | |
units | body | number | |
unit_name | body | string | |
currency | body | string | Default USD. |
occurred_at | body | string, date-time | |
project_id | body | string, uuid | |
sequence_id | body | string, uuid | |
mission_id | body | string, uuid | |
mailbox_id | body | string, uuid | |
domain | body | string | A sending domain. |
integration_id | body | string, uuid | |
ref | body | string | Idempotency key, e.g. apollo:run:123. |
note | body | string | |
Responses: 200 The ref was recorded before; the existing entry, 201 Recorded, 400 Error
get/v1/workspaces/{ws}/spend/{id}
Get a spend entry
Scope: outcomes.read.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 200 The entry, 404 Error
delete/v1/workspaces/{ws}/spend/{id}
Delete a spend entry
Scope: outcomes.manage.
For entries recorded by mistake. The deletion is in the audit log with the amount.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 204 Deleted, 404 Error
get/v1/workspaces/{ws}/spend-recurring
List recurring costs
Scope: outcomes.read.
Mailbox seats, subscriptions, people. Reports spread each over the days it was active.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 200 Recurring costs
post/v1/workspaces/{ws}/spend-recurring
Add a recurring cost
Scope: outcomes.manage.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
name * | body | string | |
category * | body | "data" | "verification" | "mailboxes" | "domains" | "sending" | "software" | "people" | "ads" | "other" | |
provider | body | string | |
amount_cents * | body | integer | |
currency | body | string | Default USD. |
every | body | "month" | "year" | Default month. |
starts_on | body | string, date | |
ends_on | body | string, date | |
project_id | body | string, uuid | |
sequence_id | body | string, uuid | |
note | body | string | |
Responses: 201 Added, 400 Error
put/v1/workspaces/{ws}/spend-recurring/{id}
Change a recurring cost
Scope: outcomes.manage.
Replaces every field. To stop a cost, set ends_on; past reports keep it.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
name * | body | string | |
category * | body | "data" | "verification" | "mailboxes" | "domains" | "sending" | "software" | "people" | "ads" | "other" | |
provider | body | string | |
amount_cents * | body | integer | |
currency | body | string | Default USD. |
every | body | "month" | "year" | Default month. |
starts_on | body | string, date | |
ends_on | body | string, date | |
project_id | body | string, uuid | |
sequence_id | body | string, uuid | |
note | body | string | |
Responses: 200 Updated, 400 Error, 404 Error
delete/v1/workspaces/{ws}/spend-recurring/{id}
Delete a recurring cost
Scope: outcomes.manage.
Removes it from every report, past ones included. Set ends_on instead to keep history.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 204 Deleted, 404 Error
get/v1/workspaces/{ws}/spend-rates
List unit prices
Scope: outcomes.read.
Every rate, plus a zero-priced row for each provider and unit used in the ledger without one, so it is clear what still needs a price.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 200 Rates
put/v1/workspaces/{ws}/spend-rates
Set what a unit costs
Scope: outcomes.manage.
Providers match without case. unit_price_micros is millionths of the currency unit: a $0.004 credit is 4000.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
provider * | body | string | |
unit_name * | body | string | |
unit_price_micros * | body | integer | |
currency | body | string | Default USD. |
Responses: 200 The rate, 400 Error
delete/v1/workspaces/{ws}/spend-rates
Remove a unit price
Scope: outcomes.manage.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
provider * | query | string | |
unit_name * | query | string | |
Responses: 204 Removed, 404 Error
missions
get/v1/workspaces/{ws}/missions
List missions
Scope: missions.read.
Waiting for approval first, then running, paused, drafts and ended.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
status | query | string | Comma-separated statuses. |
project_id | query | string, uuid | |
Responses: 200 Missions
post/v1/workspaces/{ws}/missions
Create a mission
Scope: missions.run.
Starts as a draft: writes made in it are dry
runs until a person approves it. A mission created with an API token
is run by that token; a person can assign any token with token_id.
A token bound to a project creates missions only in that project.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 201 Created, 400 Error, 403 Error
post/v1/workspaces/{ws}/missions/plan
Plan a mission from a goal
Scope: missions.run.
Type a goal in plain words ("book 10 meetings
with fintech CFOs in Australia by 30 November") and Claude drafts
the mission: a measurable goal, steps, instructions for the agent,
limits sized to your mailboxes, and the connectors it needs. The
draft is saved as a mission in status draft, with a connect request
for each missing connector and any questions for you. Nothing runs
until a person approves it.
Uses the workspace's Claude connection (connect it under Connectors
with your own API key). Without one the call fails with 409
connector_needed. Claude is sent the goal, the project brief and a
summary of the workspace, never lead lists or email addresses.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
goal * | body | string | |
project_id | body | string, uuid | Plan inside this project, using its brief. |
Responses: 201 The draft mission and what the planner proposed, 400 Error, 403 Error, 409 Error, 502 Error
get/v1/workspaces/{ws}/missions/{id}
Check in on a mission
Scope: missions.read.
What an agent reads before it acts: the
mission, the project brief (and whether it changed since approval),
limits, progress, open connect requests and the latest notes.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 200 The mission and its context, 404 Error
patch/v1/workspaces/{ws}/missions/{id}
Change a mission
Scope: missions.run.
Once a mission is approved, changing its mode,
limits, token or project also needs missions.approve, and an agent
cannot change its own. An ended mission cannot change.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
name | body | string | |
project_id | body | string, uuid | |
goal | body | string | The goal in words. |
goal_metric | body | "meetings" | "replies" | "sends" | "leads" | |
goal_target | body | integer | |
instructions | body | string | Guidance on top of the project brief (Markdown). |
plan | body | string | The agent's plan (Markdown). |
mode | body | "dry_run" | "approve_writes" | "autonomous" | dry_run: writes recorded, never run. approve_writes: each write waits for a person. autonomous: writes run within the limits. |
token_id | body | string, uuid | The only token that may act in the mission. |
max_sends | body | integer | |
max_spend_cents | body | integer | US cents |
ends_at | body | string, date-time | The mission ends itself at this time. |
Responses: 200 Updated, 400 Error, 403 Error, 409 Error
post/v1/workspaces/{ws}/missions/{id}/submit
Submit the plan for approval
Scope: missions.run.
From draft. Writes stay dry runs until approved.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
plan | body | string | Markdown. |
Responses: 200 Submitted, 409 Error
post/v1/workspaces/{ws}/missions/{id}/approve
Approve and start a mission
Scope: missions.approve.
A person, or an approver token that is not
the mission's own. Records the project brief version it was
approved against.
runner: builtin hands the mission to Outflare's own agent, which
runs it in turns with the workspace's Claude key. It gets a token of
its own (operator scopes, never more than yours, never
missions.approve) and goes through the same gate as any agent, so
the mode still decides whether its writes run, wait for you or are
dry runs. A turn runs at once, whenever a person writes to the
mission or decides on a held change, and when the agent asks to look
again. Answers 409 connector_needed until Claude is connected.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
mode | body | "dry_run" | "approve_writes" | "autonomous" | dry_run: writes recorded, never run. approve_writes: each write waits for a person. autonomous: writes run within the limits. |
note | body | string | |
runner | body | "builtin" | "external" | Who carries the mission out. Left out, it stays as it is (external for a new mission). |
Responses: 200 Running, 403 Error, 409 Error
post/v1/workspaces/{ws}/missions/{id}/pause
Pause a mission
Scope: missions.run
, so an agent can pause itself. Writes are refused and its campaigns stop sending until it resumes.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
reason | body | string | |
Responses: 200 Paused, 409 Error
post/v1/workspaces/{ws}/missions/{id}/resume
Resume a paused mission
Scope: missions.approve
, and not the mission's own agent.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 200 Running, 403 Error, 409 Error
post/v1/workspaces/{ws}/missions/{id}/stop
Stop a mission now
Scope: missions.run.
Ends it: held writes are canceled, its campaigns are paused, and further calls in it are refused.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
reason | body | string | |
Responses: 200 Stopped, 409 Error
post/v1/workspaces/{ws}/missions/{id}/complete
Finish a mission with a report
Scope: missions.run.
The agent's final report, in Markdown. Its campaigns are paused.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
report | body | string | |
Responses: 200 Completed, 409 Error
get/v1/workspaces/{ws}/missions/{id}/calls
Every call made in the mission, newest first
Scope: missions.read.
What a write changed is in the audit log under the same request_id.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
writes | query | boolean | Only writes. |
before | query | integer | A call id |
limit | query | integer | |
Responses: 200 Calls
get/v1/workspaces/{ws}/missions/{id}/actions
Writes the mission held or dry-ran
Scope: missions.read.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
status | query | string | Comma-separated. |
Responses: 200 Actions
get/v1/workspaces/{ws}/missions/{id}/actions/{action}
One held write, with its decision and result
Scope: missions.read.
Agents poll this after a 202.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
action * | path | string, uuid | |
Responses: 200 The action, 404 Error
post/v1/workspaces/{ws}/missions/{id}/actions/{action}/approve
Approve and run a held write
Scope: missions.approve.
Runs the stored request as the agent that
made it, through every normal check, and keeps the response as the
result. Works on pending writes, and on dry runs once the mission
is running. Never by the agent that made it.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
action * | path | string, uuid | |
note | body | string | |
Responses: 200 The action, 403 Error, 409 Error
post/v1/workspaces/{ws}/missions/{id}/actions/{action}/reject
Reject a held write
Scope: missions.approve.
A note is passed to the agent as an instruction.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
action * | path | string, uuid | |
note | body | string | |
Responses: 200 Rejected, 409 Error
get/v1/workspaces/{ws}/missions/{id}/updates
Notes between the agent and people
Scope: missions.read.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
open_requests | query | boolean | Only connect requests not yet resolved. |
before | query | integer | |
limit | query | integer | |
Responses: 200 Updates
post/v1/workspaces/{ws}/missions/{id}/updates
Post a note, question, instruction or connect request
Scope: missions.run.
kind connect_request asks a person to connect
a tool the agent needs (they paste the key or sign in with OAuth);
give connector as the connector id.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
kind | body | "note" | "progress" | "question" | "instruction" | "connect_request" | |
body * | body | string | |
connector | body | string | |
Responses: 201 Posted, 400 Error, 409 Error
post/v1/workspaces/{ws}/missions/{id}/updates/{update}/resolve
Close a connect request
Scope: missions.run.
The tool was connected, or a person decided not to.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
update * | path | integer | |
note | body | string | |
Responses: 204 Resolved, 409 Error
get/v1/workspaces/{ws}/mission-actions
Writes waiting for a person, across missions
Scope: missions.read.
The approval inbox.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 200 Pending actions
imports
get/v1/workspaces/{ws}/integrations/{id}/import-preview
See what an import from another sequencer would bring over
Scope: integrations.read.
Reads the connected Instantly or Smartlead account live: campaigns with their steps, and sending accounts matched to this workspace's mailboxes by address. Changes nothing.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 200 The outside account's campaigns and sending accounts, 400 Error, 404 Error, 422 Error, 502 Error
post/v1/workspaces/{ws}/integrations/{id}/imports
Import campaigns, leads and mailboxes from another sequencer
Scope: sequences.manage
, plus leads.manage when importing leads. Runs
in the background; read it with GET /imports/{id}. Campaigns become
draft sequences, so nothing sends until someone starts them. Leads
keep the step they reached and the mailbox that wrote to them;
bounced and unsubscribed leads go on the suppression list. Running it
again updates the same sequences instead of duplicating them.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
campaign_ids | body | string[] | Only these campaigns. Default every campaign. |
leads | body | boolean | Default true. |
mailboxes | body | boolean | Match sending accounts. Default true. |
Responses: 202 Queued, 400 Error, 403 Error, 404 Error
get/v1/workspaces/{ws}/imports
List imports
Scope: sequences.read.
The 50 newest.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 200 Imports, newest first
get/v1/workspaces/{ws}/imports/{id}
Read an import and what it did
Scope: sequences.read.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 200 The import, 404 Error
reports
get/v1/workspaces/{ws}/reports
Outreach and deliverability report
Scope: sequences.read.
Sends, leads contacted, new leads and follow-ups,
failures, policy blocks, bounces, replies (and replied leads), auto-replies,
opt-outs, unsubscribes and warm-up placement, with reply, bounce, opt-out
and placement rates. Totals for the period, and rows by day, week,
sequence, step, mailbox or domain. Default period is the last 30 days.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
from | query | string | A date (2026-10-01) or RFC 3339 time. |
to | query | string | A date (inclusive) or RFC 3339 time. Default now. |
group_by | query | "day" | "week" | "sequence" | "step" | "mailbox" | "domain" | |
timezone | query | string | IANA zone for dates and day buckets. Default UTC. |
sequence_id | query | string, uuid | |
mailbox_id | query | string, uuid | |
domain | query | string | |
Responses: 200 The report, 400 Error
projects
get/v1/workspaces/{ws}/projects
List projects
Scope: projects.read.
A project is one go-to-market motion: an offer
sold to one ideal customer in one market. It holds the brief people
and agents work from and owns domains, mailboxes, lead lists and
sequences. A project token sees only its own project.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
status | query | "active" | "paused" | "archived" | "all" | Default lists every project but archived ones. |
Responses: 200 Projects by name, archived last
post/v1/workspaces/{ws}/projects
Create a project
Scope: projects.manage
, not available to project tokens. Names are unique in the workspace, ignoring case.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 201 The project, 400 Error
get/v1/workspaces/{ws}/projects/{id}
Get a project
Scope: projects.read.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 200 The project, 404 Error
patch/v1/workspaces/{ws}/projects/{id}
Edit a project's brief, status or daily send limit
Scope: projects.manage.
A change to offer, audience, market, brief or
icp bumps brief_version. Send the brief_version you read to make
sure you are not overwriting someone else's edit: if the brief has
changed since, the update fails with 409 brief_changed. status:
paused holds every send from the project's sequences; archived
also hides it from the default list.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
name | body | string | |
status | body | "active" | "paused" | "archived" | |
offer | body | string | |
audience | body | string | |
market | body | string | |
brief | body | string | |
icp | body | | Replaces the whole ICP. Null clears it. |
daily_send_limit | body | integer | |
brief_version | body | integer | Updates only: the version your edit is based on. A brief edit fails with 409 if the brief changed since. |
Responses: 200 The project, 400 Error, 404 Error, 409 Error
delete/v1/workspaces/{ws}/projects/{id}
Delete a project
Scope: projects.manage
, not available to project tokens. Its domains,
mailboxes, lists and sequences stay and become shared by the
workspace. Fails with 409 project_has_tokens while the project has
live API tokens; revoke them first, or archive the project instead.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 204 Deleted, 404 Error, 409 Error
get/v1/workspaces/{ws}/projects/{id}/brief
Read a project's brief
Scope: projects.read.
What an agent should read before writing copy,
building a list or planning a campaign for the project: the
structured fields plus the whole brief as one Markdown document.
Keep version and compare it later to know the brief moved.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 200 The brief, 404 Error
post/v1/workspaces/{ws}/projects/{id}/add
Move domains, mailboxes, lists or sequences into a project
Scope: projects.manage
, plus mailboxes.manage for domains and
mailboxes, leads.manage for lists and sequences.manage for
sequences. Not available to project tokens. Records in another
project move to this one. A domain brings its mailboxes unless
with_mailboxes is false. A project's mailboxes only send for that
project's sequences, so moving one can take it off a sequence (it
finishes follow-ups first).
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
domains | body | string[] | |
mailbox_ids | body | string, uuid[] | |
lead_list_ids | body | string, uuid[] | |
sequence_ids | body | string, uuid[] | |
with_mailboxes | body | boolean | Whether a domain's mailboxes move with it. Default true. |
Responses: 200 How many records moved. Unknown ids and names are ignored, 400 Error, 403 Error, 404 Error
post/v1/workspaces/{ws}/projects/{id}/remove
Make a project's domains, mailboxes, lists or sequences shared again
Signed in
Same scopes as addToProject. Only records in this project change.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
domains | body | string[] | |
mailbox_ids | body | string, uuid[] | |
lead_list_ids | body | string, uuid[] | |
sequence_ids | body | string, uuid[] | |
with_mailboxes | body | boolean | Whether a domain's mailboxes move with it. Default true. |
Responses: 200 How many records moved, 400 Error, 403 Error, 404 Error
allocation
get/v1/workspaces/{ws}/teams
List teams
Scope: members.read.
Teams own sequences and senders. A workspace with no teams shares every mailbox.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 200 Teams by name
post/v1/workspaces/{ws}/teams
Create a team
Scope: members.manage.
Names are unique in the workspace, ignoring case.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
name | body | string | |
allocation_mode | body | "suggest" | "automatic" | |
member_ids | body | string, uuid[] | |
Responses: 201 The team, 400 Error
patch/v1/workspaces/{ws}/teams/{id}
Rename a team, change its mode or replace its members
Scope: members.manage.
member_ids replaces the whole list when sent.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
name | body | string | |
allocation_mode | body | "suggest" | "automatic" | |
member_ids | body | string, uuid[] | |
Responses: 200 The team, 400 Error, 404 Error
delete/v1/workspaces/{ws}/teams/{id}
Delete a team
Scope: members.manage.
Its sequences and senders stay, without a team.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 204 Deleted, 404 Error
get/v1/workspaces/{ws}/senders
List senders
Scope: mailboxes.read.
A sender is who mailboxes send as: a person, a
persona, or a shared identity. Each mailbox has at most one sender,
always confirmed by a person or agent, never guessed.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 200 Senders by name
post/v1/workspaces/{ws}/senders
Create a sender
Scope: mailboxes.manage.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
name | body | string | |
kind | body | "person" | "persona" | "shared" | |
user_id | body | string, uuid | |
status | body | "active" | "retired" | |
team_ids | body | string, uuid[] | |
Responses: 201 The sender, 400 Error
patch/v1/workspaces/{ws}/senders/{id}
Change a sender, or retire it
Scope: mailboxes.manage.
A retired sender's mailboxes finish their follow-ups and take no new leads.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
name | body | string | |
kind | body | "person" | "persona" | "shared" | |
user_id | body | string, uuid | |
status | body | "active" | "retired" | |
team_ids | body | string, uuid[] | |
Responses: 200 The sender, 400 Error, 404 Error
delete/v1/workspaces/{ws}/senders/{id}
Delete a sender
Scope: mailboxes.manage.
Its mailboxes become unconfirmed.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 204 Deleted, 404 Error
get/v1/workspaces/{ws}/senders/matches
Suggest senders for unconfirmed mailboxes
Scope: mailboxes.read.
Matches a mailbox to a sender only when its
display name is exactly the sender's name. Confirm each with
POST /mailboxes/sender.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 200 Matches, plus how many mailboxes have no confirmed sender
post/v1/workspaces/{ws}/mailboxes/sender
Confirm who mailboxes send as, in bulk
Scope: mailboxes.manage.
A null sender_id clears it.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
mailbox_ids * | body | string, uuid[] | |
sender_id * | body | string, uuid | |
Responses: 200 How many mailboxes changed, 400 Error
get/v1/workspaces/{ws}/allocation/settings
Get the workspace's allocation mode
Scope: sequences.read.
Teams and sequences can override the mode.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 200 The mode
patch/v1/workspaces/{ws}/allocation/settings
Set the workspace's allocation mode
Scope: members.manage.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
mode * | body | "suggest" | "automatic" | automatic: the allocator assigns mailboxes itself and explains each change. suggest: it proposes changes for a person to apply. |
Responses: 200 The mode
get/v1/workspaces/{ws}/allocation/plan
Dry run, showing what the allocator would change now
Scope: sequences.read.
Changes nothing.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 200 Planned changes and each active sequence's capacity
post/v1/workspaces/{ws}/allocation/run
Plan and apply now
Scope: sequences.manage.
The allocator also runs every minute and
after any relevant change. In suggest mode, and for changes that need
another team's or the owner's approval, it records suggestions instead.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 200 What was applied and what was suggested
get/v1/workspaces/{ws}/allocation/suggestions
List suggestions waiting on a person
Scope: sequences.read.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
sequence_id | query | string, uuid | |
Responses: 200 Suggestions, approvals first
post/v1/workspaces/{ws}/allocation/suggestions/{id}/apply
Apply or approve a suggestion
Scope: sequences.manage.
A team_approval needs a member of that team,
or a workspace owner or admin. An owner_approval needs a person, not
an API token. Fails with 409 if the mailbox changed since.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 200 The change made, 403 Error, 409 Error
post/v1/workspaces/{ws}/allocation/suggestions/{id}/decline
Decline a suggestion, so it is not proposed again
Scope: sequences.manage.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 204 Declined, 404 Error
get/v1/workspaces/{ws}/allocation/changes
Mailbox assignment history, newest first
Scope: sequences.read.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
sequence_id | query | string, uuid | |
mailbox_id | query | string, uuid | |
limit | query | integer | |
Responses: 200 Changes
post/v1/workspaces/{ws}/allocation/changes/{id}/undo
Undo a change
Scope: sequences.manage.
Only the latest change to a mailbox can be
undone. Undoing an automatic choice also stops the allocator from
making it again.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 200 The reversing change, 400 Error, 409 Error
get/v1/workspaces/{ws}/allocation/attention
What needs a person
Scope: sequences.read.
Approvals, suggestions to review, shortages, follow-ups whose mailbox is gone and unconfirmed senders.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 200 Items needing attention
post/v1/workspaces/{ws}/mailboxes/assign
Assign mailboxes to a sequence by hand
Scope: sequences.manage.
A mailbox with leads mid-sequence elsewhere
drains first: it finishes those follow-ups, then joins. Locks are
honoured; a mailbox locked elsewhere is refused.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
mailbox_ids * | body | string, uuid[] | |
sequence_id * | body | string, uuid | |
Responses: 200 One result per mailbox, 400 Error
post/v1/workspaces/{ws}/mailboxes/release
Take mailboxes off their sequence
Scope: sequences.manage.
Mailboxes with leads in flight drain first.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
mailbox_ids * | body | string, uuid[] | |
Responses: 200 One result per mailbox
post/v1/workspaces/{ws}/mailboxes/lock
Lock mailboxes, or clear their locks
Scope: mailboxes.manage.
sequence: keep on this sequence (assigns it
now). team: only this team's sequences. manual_only: the allocator
never touches it. A null kind clears the lock. until is optional.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
mailbox_ids * | body | string, uuid[] | |
kind * | body | "sequence" | "team" | "manual_only" | |
sequence_id | body | string, uuid | |
team_id | body | string, uuid | |
until | body | string, date-time | |
note | body | string | |
Responses: 200 Mailboxes changed, and any assignments a sequence lock made, 400 Error
get/v1/workspaces/{ws}/sequences/{id}/allocation
A sequence's mailboxes, capacity, suggestions and history
Scope: sequences.read.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 200 The sequence's allocation, 404 Error
post/v1/workspaces/{ws}/sequences/{id}/orphaned-follow-ups
Decide what happens to follow-ups whose mailbox is gone
Scope: sequences.manage.
cancel stops them. handoff sends the next
step from another of the sequence's mailboxes as a fresh email, not a
reply, since the new sender never wrote before.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
action * | body | "cancel" | "handoff" | |
Responses: 200 How many leads changed
infrastructure
get/v1/workspaces/{ws}/infrastructure
Mailboxes by lifecycle stage, the ones not ready, and plans in progress
Scope: infrastructure.read.
Counts of mailboxes in each lifecycle
stage (warming, ready, resting, retired), every mailbox that is not
ready with the reason and until when, the plans that are not finished,
and the suppliers plans can buy from on this server.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 200 Overview
post/v1/workspaces/{ws}/infrastructure/preview
Draft a plan without saving it
Scope: infrastructure.read.
Takes the same fields as creating a plan
and returns the domains, mailboxes, timeline, daily capacity and
warnings it would have. Nothing is saved or bought.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
name | body | string | |
project_id | body | string, uuid | |
supplier | body | string | manual (you buy; the plan waits for you), or a supplier connector such as cheapinboxes. See suppliers on GET /infrastructure. |
supplier_integration_id | body | string, uuid | The connected supplier account to buy with. |
provider | body | "google" | "microsoft" | |
domain_count | body | integer | |
mailboxes_per_domain | body | integer | |
brand | body | string | Domain names are made from it |
personas | body | object[] | |
domains | body | string[] | Domain names you chose. The rest are suggested from brand. |
ready_by | body | string, date | |
warmup_days | body | integer | |
mailbox_daily_limit | body | integer | Cold emails a day per mailbox once ready. |
rest_below | body | integer | A ready mailbox rests when its warm-up inbox placement falls below this percent. |
retire_after_days | body | integer | Retire a mailbox that rested this long without recovering. Null never does. |
notes | body | string | |
Responses: 200 The draft, 400 Error
post/v1/workspaces/{ws}/infrastructure/move
Move mailboxes to warming, ready, resting or retired
Scope: infrastructure.manage.
Works on any mailbox, including ones
you imported yourself. Only ready mailboxes send cold email; warm-up
carries on while warming and resting. Retiring pauses the mailbox and
turns warm-up off for good; its unfinished follow-ups wait for you to
cancel them or hand them to another mailbox. A mailbox that cannot
make the move is returned with skipped saying why.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
mailbox_ids * | body | string, uuid[] | |
stage * | body | "warming" | "ready" | "resting" | "retired" | Where a mailbox is in its working life. Only ready mailboxes send cold
email. warming: warming up. resting: no cold email for a while,
warm-up continues. retired: out of use for good. |
reason | body | string | Shown on the mailbox and in the audit log. |
until | body | string, date-time | Resting: when the rest ends (default 7 days). Warming: the earliest it can be ready (default 14 days). |
auto_rest | body | boolean | Rest on its own when warm-up inbox placement drops, and come back when it recovers. |
cancel_at_supplier | body | boolean | Retiring a mailbox a plan bought also cancels it at the supplier, at the end of the period. |
Responses: 200 What happened to each mailbox, 400 Error
get/v1/workspaces/{ws}/infra-plans
List infrastructure plans
Scope: infrastructure.read.
Newest first, without their items.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 200 Plans
post/v1/workspaces/{ws}/infra-plans
Draft a plan for domains and mailboxes
Scope: infrastructure.manage.
"10 domains and 30 mailboxes for this
project by the 14th" is domain_count: 10, mailboxes_per_domain: 3,
ready_by: "2026-11-14", project_id. Domain names come from brand
unless you list them in domains; listing a domain the workspace
already has adds mailboxes to it instead of buying it. Mailbox names
come from personas. A plan with a supplier is priced in the
background; read it again until quote.status is ready. A draft
buys nothing until it is approved.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
Responses: 201 The draft plan, 400 Error
get/v1/workspaces/{ws}/infra-plans/{id}
Get a plan with every domain and mailbox and where each one is
Scope: infrastructure.read
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 200 The plan, 404 Error
patch/v1/workspaces/{ws}/infra-plans/{id}
Change a draft plan
Scope: infrastructure.manage.
Drafts only. Domains already in the plan
are kept unless you send domains; ones the supplier said are taken
are replaced with new suggestions.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
name | body | string | |
project_id | body | string, uuid | |
supplier | body | string | manual (you buy; the plan waits for you), or a supplier connector such as cheapinboxes. See suppliers on GET /infrastructure. |
supplier_integration_id | body | string, uuid | The connected supplier account to buy with. |
provider | body | "google" | "microsoft" | |
domain_count | body | integer | |
mailboxes_per_domain | body | integer | |
brand | body | string | Domain names are made from it |
personas | body | object[] | |
domains | body | string[] | Domain names you chose. The rest are suggested from brand. |
ready_by | body | string, date | |
warmup_days | body | integer | |
mailbox_daily_limit | body | integer | Cold emails a day per mailbox once ready. |
rest_below | body | integer | A ready mailbox rests when its warm-up inbox placement falls below this percent. |
retire_after_days | body | integer | Retire a mailbox that rested this long without recovering. Null never does. |
notes | body | string | |
Responses: 200 The plan, 400 Error, 409 Error
delete/v1/workspaces/{ws}/infra-plans/{id}
Delete a draft or cancelled plan
Scope: infrastructure.manage.
Domains and mailboxes it built stay.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 204 Deleted, 404 Error, 409 Error
post/v1/workspaces/{ws}/infra-plans/{id}/approve
Approve a plan, which starts buying
Scope: infrastructure.approve
(owners and admins; give it to an agent
token only if it may spend). Fails with 409 while the plan has a
blocking warning. When the plan has a price, send once_cents and
monthly_cents exactly as its quote shows them, so a price that
changed is never approved by accident. Customers pay the supplier
directly, on their own account.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
once_cents | body | integer, int64 | |
monthly_cents | body | integer, int64 | |
Responses: 200 The plan, now building, 409 Error
post/v1/workspaces/{ws}/infra-plans/{id}/cancel
Stop a plan
Scope: infrastructure.manage.
Steps not done yet are cancelled. An
order already placed with a supplier is not undone; cancel it in your
supplier account if you need to.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 200 The plan, 409 Error
post/v1/workspaces/{ws}/infra-plans/{id}/bought
Tell a plan you bought its domains
Scope: infrastructure.manage.
For plans you buy yourself (supplier:
manual). Moves the domains on to the DNS check. A domain also moves
on by itself once its MX records point at the plan's provider.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
domains | body | string[] | The domains bought; every domain waiting to be bought when left out. |
Responses: 200 How many domains moved on, 409 Error
post/v1/workspaces/{ws}/infra-plans/{id}/refresh
Get a new quote for a draft, or check a building plan now
Scope: infrastructure.manage.
Runs in the background. Building plans are also checked every 5 minutes on their own.
| Parameter | In | Type | Description |
|---|
ws * | path | string, uuid | |
id * | path | string, uuid | |
Responses: 202 Queued, 404 Error