Create Sub-Account

Provision a new sub-account, optionally link it to a GHL location, apply a pricing plan, and send an owner invitation — all in one call.

POST

Create Sub-Account

Provision a new sub-account inside your agency workspace. Optionally link it to a GoHighLevel location, apply an agency pricing plan, and email an invitation to the sub-account owner — all in one call.

Endpoint

POST https://crmwebhook.com/functions/v1/create-subaccount-webhook

Headers

HeaderValueRequired
X-API-Key or AuthorizationAgency API key (cfy_...)Required
Content-Typeapplication/jsonRequired

Request Body

{
  "name": "Acme Roofing",
  "email": "owner@acmeroofing.com",
  "locationID": "abc123XYZ",
  "plan": "starter"
}

Body Parameters

FieldTypeRequiredDescription
emailstringRequiredEmail address of the sub-account owner. An invitation email is sent here.
namestringConditionalDisplay name for the sub-account. Required if locationID is not provided. If both are provided, the GHL location name takes precedence.
locationIDstringConditionalGHL location ID. Fetches the location’s name and timezone from GHL and auto-connects the sub-account. Either locationID or name must be present.
planstringOptionalSlug of an agency pricing plan. The sub-account inherits the plan’s limits, features, and rebilling pricing. If omitted, inherits the organization’s defaults.

Example — Minimal

curl -X POST https://crmwebhook.com/functions/v1/create-subaccount-webhook \
  -H "X-API-Key: cfy_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Roofing",
    "email": "owner@acmeroofing.com"
  }'

Example — With GHL location + plan

curl -X POST https://crmwebhook.com/functions/v1/create-subaccount-webhook \
  -H "X-API-Key: cfy_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "owner@acmeroofing.com",
    "locationID": "abc123XYZ",
    "plan": "starter"
  }'

Response Shape

{
  "success": true,
  "sub_account_id": "8f3b1c4d-...",
  "sub_account_slug": "acme-roofing",
  "invitation_token": "7d75abff-436d-4a2e-b501-1abedf2d58ae",
  "ghl_connected": true,
  "plan": "starter"
}

Response Fields

FieldTypeDescription
successbooleanAlways true for 201
sub_account_idstring (UUID)Internal ID of the new sub-account
sub_account_slugstringURL-safe slug (may have a timestamp suffix if slug already existed)
invitation_tokenstring (UUID)Token for the invitation email link
ghl_connectedbooleantrue if GHL was linked. Always false when locationID is omitted
planstring or nullApplied plan slug, or null if no plan was passed
ghl_errorstringPresent only when locationID was provided but GHL connection failed. Sub-account is still created.

Response Codes

StatusMeaning
201Sub-account created successfully
400Missing email, or neither name nor locationID provided
401Missing or invalid API key
403Organization not on White Label/SaaS plan, org inactive, or sub-account limit reached
404Organization not found, or plan slug not found for this organization
500Internal error (sub-account insert or invitation failed)

What happens behind the scenes

  1. Authenticates the API key and looks up the organization
  2. Verifies the org is on a White Label or SaaS Mode plan
  3. Checks the org hasn’t hit its max_sub_accounts limit
  4. If plan is provided, loads the agency pricing plan limits; otherwise uses org defaults
  5. If locationID is provided, fetches the GHL location name and timezone
  6. Creates the sub-account row with limits, features, and rebilling config
  7. Creates a zero-balance wallet for the sub-account
  8. Creates an invitation with role sub_account_owner (expires in 7 days)
  9. Sends the invitation email via the agency’s Resend config
  10. If locationID was provided, auto-connects the GHL location
© 2026 Centerfy AI. All rights reserved.