v1

latestOpenAPI 3.1.02026-07-2210284274.4 KB
Onboarding

Create or adopt my organization

Bootstrap the caller's organization explicitly. Use this when the caller wants to control the organization name, company_type, revenue_tier, or is_personal flag before any agents are registered.

Most storefront-style integrations don't need this callPOST /api/me/agents will auto-create an org for a fresh OAuth user (corporate or personal workspace based on the email domain) and surface org_auto_created: true in the response. Reach for POST /api/organizations only when the auto-derived defaults aren't acceptable.

Three outcomes depending on the caller's state:

  • Fresh create (most common): a new WorkOS organization is created, the caller is added as owner, the corporate domain is recorded as email-verified, and ToS / privacy-policy acceptance is logged from the request context. Returns { success: true, organization: { id, name } }.

  • Prospect adoption: an organization with the caller's email domain already exists as a prospect (the registry pre-recorded it from a brand crawl but no human had claimed it yet). The caller is promoted to owner of the existing record instead of forking a duplicate. Returns { id, name, adopted: true }.

  • Already-active conflict: the org exists and is already claimed by another paying member or a previously joined user. Returns 409 with the existing org id so the caller can switch to a join-request flow (POST /api/organizations/:orgId/join-requests) instead of trying to register a duplicate.

Tier transitions happen via the billing flow only — there is no membership_tier field on this endpoint. After org creation, send the user to POST /api/checkout-session (or the /dashboard/membership page) to start a subscription; the Stripe webhook is the sole writer of organizations.membership_tier.

Rate-limited per user: 15 failed attempts per hour; successful calls do not count against the limit so a legitimate registration is never penalized by earlier validation errors.

post/api/organizations

Request body

organization_namestring required

Display name for the organization. Used both as the org row name and (when auto-bootstrapping a member profile via the first agent registration) as the profile's display_name.

is_personalboolean

Set to true to create a personal workspace instead of a corporate organization. Personal workspaces skip corporate-domain verification, are limited to one per user, and cannot host the company_* membership tiers.

company_type'adtech' | 'agency' | 'brand' | 'publisher' | 'data' | 'ai' | 'other'

Coarse classification of the organization's role in the open ad ecosystem. Drives default verification badges and the member profile's display category.

revenue_tier'under_1m' | '1m_5m' | '5m_50m' | '50m_250m' | '250m_1b' | '1b_plus'

Annual revenue band, USD. Drives membership-tier eligibility for company-tier seats.

marketing_opt_inboolean

Whether the caller opted in to AAO marketing communications. Recorded once per user (not overwritten on subsequent calls). Independent of Terms-of-Service consent, which is recorded server-side from the request context.

Example request

{
  "organization_name": "Acme Media"
}

Response

Prospect adoption — an existing prospect organization for this domain was claimed by the caller. Body is { id, name, adopted: true }.

successboolean
idstring

Set on the prospect-adoption path: when an org with the user's email domain already exists in a prospect state (i.e. the registry pre-recorded it from a brand crawl but no human had claimed it yet), this call adopts that org for the caller instead of creating a new one.

namestring
adoptedboolean

true when the response is the prospect-adoption path. When true, no new WorkOS organization was created — the caller is now the owner of an existing prospect record.

Example response

{
  "organization": {
    "id": "org_01HXZAB123",
    "name": "Acme Media"
  }
}