Skip to content

Create a managed client account under the calling partner.

POST
/partner/accounts
curl --request POST \
--url https://api.siteqwality.com/partner/accounts \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "display_name": "example", "contact_email": "example", "contact_name": "example" }'

The client is a perfectly ordinary account with a parent pointer: it has its own monitors, its own status pages, its own quotas and its own notification routing, and the partner works in it through the X-SQ-Account header. Three things make it not-ordinary, all decided here rather than inside the shared provisioning seam:

  • No Stripe customer. The partner is billed on one subscription; a client is never billed directly, so it never gets a customer object to leak or reconcile.
  • No welcome email. The contact never asked us for an account. A “welcome to SiteQwality” email out of nowhere is the partner’s relationship to manage, not ours.
  • A Stytch organization with no member and no session. Nobody is signing in yet. The organization exists up front so the partner’s later invite has somewhere to land, and the local user row (which the account needs, for primary_user_id) carries a NULL stytch_member_id until then.
Media type application/json

Body for POST /partner/accounts.

object
display_name
required

The partner’s label for this client, e.g. “Acme Corp”. Not shown to the client and not client-editable: it is how the partner console lists them, and it names the client’s Stytch organization.

string
contact_email
required

The client’s real contact address. It becomes the child account’s primary user and the address its default notification group alerts, so an outage on the client’s site reaches the client rather than the partner.

Must be distinct across the partner’s client accounts. See Database::partner_client_account_id_by_contact_email for why that is a pricing rule and not a data-hygiene preference.

string
contact_name

The contact’s name, when the partner knows it. Absent is normal.

string | null
Example generated
{
"display_name": "example",
"contact_email": "example",
"contact_name": "example"
}

Client account created

Media type application/json

One managed client account, as the console lists it and as create answers.

object
account_id
required

The client’s account id. This is the value the partner sends as X-SQ-Account to open the client in the ordinary dashboard.

string format: uuid
display_name
string | null
contact_email

Nullable because accounts.primary_user_id carries no foreign key; see DbPartnerChildAccount::contact_email.

string | null
created_at
required
string format: date-time
suspended
required

Convenience mirror of suspended_at.is_some(), so a client list can render the badge without parsing a timestamp.

boolean
suspended_at
string | null format: date-time
monitors
required

Monitor counts for one client, in the same state-aware sense GET /monitors/totals uses: a paused monitor counts in total and paused and in neither online nor down.

object
total
required
integer format: int32
online
required
integer format: int32
down
required
integer format: int32
paused
required
integer format: int32
Example generated
{
"account_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"display_name": "example",
"contact_email": "example",
"created_at": "2026-04-15T12:00:00Z",
"suspended": true,
"suspended_at": "2026-04-15T12:00:00Z",
"monitors": {
"total": 1,
"online": 1,
"down": 1,
"paused": 1
}
}

Invalid request body

Missing or invalid authentication

No client slot left on the partner plan

Caller is not an admin, or the account is not in the partner program

That contact address already belongs to one of your clients, or to another SiteQwality account

Internal server error