Org / AWS / SES / plan snapshot

Search Documentation

Search across all developer documentation

account

Org / AWS / SES / plan snapshot

GET /v1/account
Auth required api.account.view

Returns a composed snapshot of the calling org's onboarding state: organization metadata, the connected AWS account and live SES send quota, the production-access request status, the CloudFormation template version, and the active plan. The response is cached per-org for 60 seconds (a Cache-Control: max-age=60 response header advertises this), so repeated polling does not generate extra AWS or DB load.

Each top-level field is always present — sub-objects are null when the corresponding milestone has not been reached:

  • aws and send_quota are null until the customer has connected an AWS account, and also null if the live SES GetAccount call fails (the rest of the response still renders — SES failure degrades gracefully, it does not 5xx).
  • production_access is null until the customer has submitted a production-access request.
  • cloudformation is null until the customer has applied the SendOps CloudFormation stack.

aws.sandbox is the live SES sandbox flag (true while SES still has the AWS account in the default sandbox); this is distinct from production_access.status, which reflects the SendOps-side request workflow. Use this endpoint to drive onboarding UIs, detect template drift, and gate features on plan tier.

This snapshot is caller-scoped: it always describes the org whose API key made the request. There is no way to read another org's (or a customer's) onboarding or AWS state through it. When your source of truth for a contact's state lives in a different system or org, push that state onto the contact on a schedule rather than trying to observe it here — see Syncing externally-observed state.

Responses

Errors follow the RFC 7807 problem format — see the error reference.

200 Composed account snapshot application/json
org object required

Fields of org:

id string<uuid> required
name string required
slug string required
aws object | null required

Null when no AWS account has been connected, or when the live SES GetAccount call failed (the rest of the response still renders).

Fields of aws:

account_id string | null required

Null for older connections where STS hadn't returned the assumed-account ID at connect time.

region string required
sandbox boolean required

Live SES sandbox flag for the connected account. true while SES still has the account in the default sandbox, false once AWS has granted production access. Distinct from production_access.status, which tracks the SendOps-side request workflow.

production_access boolean | null required

Persisted SES production-access flag (SND-1069): true once AWS has lifted the account out of the sandbox, false while still sandboxed, null until SendOps has probed the account at least once. Unlike sandbox (derived from the live GetAccount call in this response), this is a stored value refreshed every 15 minutes — a cheap read that never costs a live SES call.

send_quota object | null required

Populated under the same conditions as aws. Values are clamped non-negative.

Fields of send_quota:

max_24_hour integer<int64> required

Constraints: 0–∞

max_send_rate integer<int64> required

Constraints: 0–∞

sent_last_24_hours integer<int64> required

Constraints: 0–∞

production_access object | null required

Null until the org has submitted a production-access request.

Fields of production_access:

status string enum required

One of: pending, under_review, granted, denied, failed

granted_at string<date-time> | null required

Non-null only when status == "granted".

cloudformation object | null required

Null when no AWS connection exists or the connection has no recorded template version.

Fields of cloudformation:

stack_name string | null required

Always null in v1 — reserved for future use.

template_version integer required

The CloudFormation template version the customer has applied.

latest_version integer required

The latest template version baked into this SendOps build.

up_to_date boolean required

template_version >= latest_version.

drift_status string | null required

Always null in v1 — reserved for future stack-drift detection.

plan object required

The plan, and where the org stands on every plan axis. version, overage_enabled, period and axes are the same snapshot the dashboard's billing page shows; it is recomputed at most every 30 seconds. They are present together or not at all: an org whose plan reports no per-axis usage gets only the first three fields.

Fields of plan:

tier string enum required

admin, sponsored, and demo are internal plan tiers but can appear in this response for orgs on those tiers.

One of: free, team, business, admin, sponsored, demo

retention_days integer required

Maximum age in days for analytics queries (messages, reports) on this plan.

api_rate_limit_per_minute integer | null required

Null means no throttle is configured for this plan.

version integer enum optional

The plan matrix the org is on. 1 is a grandfathered org that keeps the limits it had before plans gained per-axis caps: every axis then reads enforced: false and limit: null.

One of: 1, 2

overage_enabled boolean optional

true when the org may exceed its caps on every axis with an overage price, billed per unit at the end of the period. Only ever true on Business.

period object optional

The usage period consumption axes count in, [start, end).

Fields of period:

start string<date-time> required
end string<date-time> required
axes array<object> optional

Every plan axis, in a stable display order.

Each entry in axes:

axis string enum required

The axis, as named in a 402 plan_limit_exceeded problem's limit_type. cdn_storage is measured in bytes (both used and limit); every other axis counts things.

One of: seats, templates, domains, aws_accounts, active_workflows, enrollments, segments, broadcasts, contacts, inbox_mints, inbox_live, inbound_domains, inbound_msgs, sites, cdn_domains, cdn_storage, verified_senders

kind string enum required

count is how many exist now; consumption is how many were used in the current period.

One of: count, consumption

used integer<int64> | null required

Null when the axis could not be counted — never read it as zero.

limit integer<int64> | null required

The cap. Null when the axis is not enforced. 0 means the plan does not include it.

enforced boolean required

Whether reaching limit refuses the next action with a 402.

overage object | null required

The price of going past limit: unit_cents for every per_units above it. Null when the axis cannot be exceeded on this plan. On Team only seats has one (extra seats are bought as an add-on); on Business it applies while overage_enabled is true.

Fields of overage:

unit_cents integer required
per_units integer<int64> required
ceiling boolean required

true for contacts: a ceiling that is never priced and has no overage on any plan. Contact us to go above it.

401 Missing, malformed, or unknown API key application/problem+json
403 Key lacks the required scope or plan limit violated application/problem+json
429 Per-org rate limit exceeded application/problem+json
500 Unexpected server-side failure. The code is internal_error. The request_id field can be quoted to SendOps support to investigate. application/problem+json