Skip to main content
Glama
zackscriven

ghl-mcp-server-v2

by zackscriven

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
GHL_API_KEYYesPrivate-integration token / OAuth access token. Env-only, never hardcoded. Fallback: HD_GHL_API_KEY.
GHL_BASE_URLNoOverride base URL for testing. Default: https://services.leadconnectorhq.com
GHL_SPECS_DIRNoPath to spec files (only used for regeneration).
GHL_TIMEOUT_MSNoRequest timeout in milliseconds. Default: 30000
GHL_ENABLE_WRITESNoDry-run safety gate. Set to 'true' or '1' to enable write operations. Default unset = read-only. Fallback: HD_GHL_ENABLE_WRITES.
GHL_ENABLED_DOMAINSNoComma-separated spec basenames (e.g., contacts,opportunities,calendars) to expose a subset of tools. Default: all.

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
ghl_brand_board_deleteA

[LEGACY FALLBACK — this endpoint is no longer in the live v3 docs (checked 2026-10-28) but is still served under the legacy Version header. Expect removal; prefer a current equivalent.] Delete a Brand Board Deletes a Brand Board Endpoint: DELETE /brand-boards/{locationId}/{id} (Version header: 2021-07-28; source: brand-boards.json) Requires a Sub-Account (location) token. OAuth scopes: brand-boards/design-kit.write

ghl_brand_board_get_by_idA

[LEGACY FALLBACK — this endpoint is no longer in the live v3 docs (checked 2026-10-28) but is still served under the legacy Version header. Expect removal; prefer a current equivalent.] Get Brand Board Retrieves a specific Brand Board by its ID Endpoint: GET /brand-boards/{locationId}/{id} (Version header: 2021-07-28; source: brand-boards.json) Requires a Sub-Account (location) token. OAuth scopes: brand-boards/design-kit.readonly

ghl_brand_board_updateA

[LEGACY FALLBACK — this endpoint is no longer in the live v3 docs (checked 2026-10-28) but is still served under the legacy Version header. Expect removal; prefer a current equivalent.] Update a Brand Board Updates an existing Brand Board Endpoint: PATCH /brand-boards/{locationId}/{id} (Version header: 2021-07-28; source: brand-boards.json) Requires a Sub-Account (location) token. OAuth scopes: brand-boards/design-kit.write

ghl_brand_board_get_by_locationA

[LEGACY FALLBACK — this endpoint is no longer in the live v3 docs (checked 2026-10-28) but is still served under the legacy Version header. Expect removal; prefer a current equivalent.] Get Brand Boards Retrieves all Brand Boards for a specific location Endpoint: GET /brand-boards/{locationId} (Version header: 2021-07-28; source: brand-boards.json) Requires a Sub-Account (location) token. OAuth scopes: brand-boards/design-kit.readonly Pagination params: limit, offset — pass them to page through full result sets.

ghl_brand_board_createA

[LEGACY FALLBACK — this endpoint is no longer in the live v3 docs (checked 2026-10-28) but is still served under the legacy Version header. Expect removal; prefer a current equivalent.] Create a new brand board Creates a new brand board with logos, colors, and fonts Endpoint: POST /brand-boards/ (Version header: 2021-07-28; source: brand-boards.json) Requires a Sub-Account (location) token. OAuth scopes: brand-boards/design-kit.write

ghl_contact_remove_from_all_campaigns_legacyA

Legacy path variant (contacts.json, 2021-07-28) of removing a contact from every campaign. Functionally equivalent to ghl_contact_remove_from_all_campaigns (v3, DELETE /contacts/{contactId}/campaigns/remove-all) — prefer the v3 tool for new integrations. Renamed from the auto-generated name to disambiguate the two distinct-but-similar endpoints (was colliding with the v3 op's derived name, which got an ugly auto '_delete2' suffix). [LEGACY FALLBACK — this endpoint is no longer in the live v3 docs (checked 2026-10-28) but is still served under the legacy Version header. Expect removal; prefer a current equivalent.] Remove Contact From Every Campaign Endpoint: DELETE /contacts/{contactId}/campaigns/removeAll (Version header: 2021-07-28; source: contacts.json) OAuth scopes: contacts.write

ghl_contact_listA

Deprecated by GoHighLevel — prefer ghl_contact_search_advanced (POST /contacts/search) for new integrations. Kept registered for legacy callers. Returns a simple paginated list filtered by an optional free-text query, not the advanced filter/sort search. [DEPRECATED per official docs — prefer the documented replacement if one exists.] [LEGACY FALLBACK — this endpoint is no longer in the live v3 docs (checked 2026-10-28) but is still served under the legacy Version header. Expect removal; prefer a current equivalent.] Get Contacts Get Contacts

Note: This API endpoint is deprecated. Please use the Search Contacts endpoint instead. Endpoint: GET /contacts/ (Version header: 2021-07-28; source: contacts.json) OAuth scopes: contacts.readonly Pagination params: startAfterId, startAfter, limit — pass them to page through full result sets.

ghl_conversation_update_custom_subtypeA

[LEGACY FALLBACK — this endpoint is no longer in the live v3 docs (checked 2026-10-28) but is still served under the legacy Version header. Expect removal; prefer a current equivalent.] Update Custom Subtype Update or archive a custom subtype. Requires agency or account admin role. Endpoint: PUT /conversations/preferences/custom-subtypes/{id} (Version header: 2021-04-15; source: conversations.json)

ghl_conversation_list_custom_subtypesA

[LEGACY FALLBACK — this endpoint is no longer in the live v3 docs (checked 2026-10-28) but is still served under the legacy Version header. Expect removal; prefer a current equivalent.] Get All Custom Subtypes Get all custom subtypes for a location Endpoint: GET /conversations/preferences/custom-subtypes (Version header: 2021-04-15; source: conversations.json)

ghl_conversation_create_custom_subtypeA

[LEGACY FALLBACK — this endpoint is no longer in the live v3 docs (checked 2026-10-28) but is still served under the legacy Version header. Expect removal; prefer a current equivalent.] Create Custom Subtype Create a new custom subtype for a location. Requires agency or account admin role. Endpoint: POST /conversations/preferences/custom-subtypes (Version header: 2021-04-15; source: conversations.json)

ghl_conversation_get_contact_unsubscription_statusA

[LEGACY FALLBACK — this endpoint is no longer in the live v3 docs (checked 2026-10-28) but is still served under the legacy Version header. Expect removal; prefer a current equivalent.] Get Contact Unsubscription Status Get all subscription statuses for a contact (all emails or specific email) Endpoint: GET /conversations/preferences/unsubscriptions/status (Version header: 2021-04-15; source: conversations.json)

ghl_conversation_user_subscription_changeA

[LEGACY FALLBACK — this endpoint is no longer in the live v3 docs (checked 2026-10-28) but is still served under the legacy Version header. Expect removal; prefer a current equivalent.] User Subscription Change Process subscription change initiated by a user (admin/agent). Supports individual custom subscription changes and resub all functionality. Legal forms are automatically created for user-initiated resubscribe actions on custom subscriptions. Endpoint: POST /conversations/preferences/unsubscriptions/user-change (Version header: 2021-04-15; source: conversations.json)

ghl_email_builder_template_deleteA

Legacy 'Email Builder' template API (2021-era, distinct from the v3 template family below — different data model, not interchangeable). [LEGACY FALLBACK — this endpoint is no longer in the live v3 docs (checked 2026-10-28) but is still served under the legacy Version header. Expect removal; prefer a current equivalent.] Delete a template Endpoint: DELETE /emails/builder/{locationId}/{templateId} (Version header: 2021-07-28; source: emails.json) Requires a Sub-Account (location) token.

ghl_email_builder_template_updateA

Legacy 'Email Builder' template API (2021-era, distinct from the v3 template family below — different data model, not interchangeable). [LEGACY FALLBACK — this endpoint is no longer in the live v3 docs (checked 2026-10-28) but is still served under the legacy Version header. Expect removal; prefer a current equivalent.] Update a template Endpoint: POST /emails/builder/data (Version header: 2021-07-28; source: emails.json) Requires a Sub-Account (location) token. OAuth scopes: emails/builder.write

ghl_email_builder_template_getA

Legacy 'Email Builder' template API (2021-era, distinct from the v3 template family below — different data model, not interchangeable). [LEGACY FALLBACK — this endpoint is no longer in the live v3 docs (checked 2026-10-28) but is still served under the legacy Version header. Expect removal; prefer a current equivalent.] Fetch email templates Fetch email templates by location id Endpoint: GET /emails/builder (Version header: 2021-07-28; source: emails.json) Requires a Sub-Account (location) token. OAuth scopes: emails/builder.readonly Pagination params: limit, offset — pass them to page through full result sets.

ghl_email_builder_template_createA

Legacy 'Email Builder' template API (2021-era, distinct from the v3 template family below — different data model, not interchangeable). [LEGACY FALLBACK — this endpoint is no longer in the live v3 docs (checked 2026-10-28) but is still served under the legacy Version header. Expect removal; prefer a current equivalent.] Create a new template Endpoint: POST /emails/builder (Version header: 2021-07-28; source: emails.json) Requires a Sub-Account (location) token. OAuth scopes: emails/builder.write

ghl_email_legacy_campaign_listA

Legacy schedule/campaign listing (2021-era, distinct from the v3 campaign family at /emails/locations/{locationId}/campaigns/emails). Supports limit/offset pagination plus status and emailStatus filters. [LEGACY FALLBACK — this endpoint is no longer in the live v3 docs (checked 2026-10-28) but is still served under the legacy Version header. Expect removal; prefer a current equivalent.] Get Campaigns Endpoint: GET /emails/schedule (Version header: 2021-07-28; source: emails.json) Requires a Sub-Account (location) token. OAuth scopes: emails/schedule.readonly Pagination params: limit, offset — pass them to page through full result sets.

ghl_oauth_get_installed_locationA

REQUIRES AN AGENCY-LEVEL (Company) TOKEN — spec security is Agency-Access-Only, no Location-Access alternative. Legacy twin of GET /oauth/installed-locations (v3); prefer the v3 op for new integrations. [LEGACY FALLBACK — this endpoint is no longer in the live v3 docs (checked 2026-10-28) but is still served under the legacy Version header. Expect removal; prefer a current equivalent.] Get Location where app is installed This API allows you fetch location where app is installed upon Endpoint: GET /oauth/installedLocations (Version header: 2021-07-28; source: oauth.json) Requires an Agency (company-level) token. OAuth access token only — Private Integration Tokens are rejected. OAuth scopes: oauth.readonly Pagination params: skip, limit — pass them to page through full result sets.

ghl_oauth_get_location_access_tokenA

REQUIRES AN AGENCY-LEVEL (Company) TOKEN — spec security is Agency-Access-Only. Body is application/x-www-form-urlencoded per spec (companyId, locationId as form fields), not JSON. Legacy twin of POST /oauth/location-token (v3); prefer the v3 op for new integrations. [LEGACY FALLBACK — this endpoint is no longer in the live v3 docs (checked 2026-10-28) but is still served under the legacy Version header. Expect removal; prefer a current equivalent.] Get Location Access Token from Agency Token This API allows you to generate locationAccessToken from AgencyAccessToken Endpoint: POST /oauth/locationToken (Version header: 2021-07-28; source: oauth.json) Requires an Agency (company-level) token. OAuth access token only — Private Integration Tokens are rejected. OAuth scopes: oauth.write

ghl_saas_get_agency_plans_deprecatedA

DEPRECATED per spec — superseded by GET /saas/agency-plans/{companyId}. REQUIRES AN AGENCY-LEVEL (Company) TOKEN. [DEPRECATED per official docs — prefer the documented replacement if one exists.] [LEGACY FALLBACK — this endpoint is no longer in the live v3 docs (checked 2026-10-28) but is still served under the legacy Version header. Expect removal; prefer a current equivalent.] Get Agency Plans Fetch all agency subscription plans for a given company ID Endpoint: GET /saas-api/public-api/agency-plans/{companyId} (Version header: 2021-04-15; source: saas-api.json) Requires an Agency (company-level) token.

ghl_saas_bulk_disable_deprecatedA

DEPRECATED per spec — superseded by POST /saas/bulk-disable-saas/{companyId}. REQUIRES AN AGENCY-LEVEL (Company) TOKEN. [DEPRECATED per official docs — prefer the documented replacement if one exists.] [LEGACY FALLBACK — this endpoint is no longer in the live v3 docs (checked 2026-10-28) but is still served under the legacy Version header. Expect removal; prefer a current equivalent.] Disable SaaS for locations Disable SaaS for locations for given locationIds Endpoint: POST /saas-api/public-api/bulk-disable-saas/{companyId} (Version header: 2021-04-15; source: saas-api.json) Requires an Agency (company-level) token.

ghl_saas_bulk_enable_deprecatedA

DEPRECATED per spec — superseded by POST /saas/bulk-enable-saas/{companyId}. REQUIRES AN AGENCY-LEVEL (Company) TOKEN. [DEPRECATED per official docs — prefer the documented replacement if one exists.] [LEGACY FALLBACK — this endpoint is no longer in the live v3 docs (checked 2026-10-28) but is still served under the legacy Version header. Expect removal; prefer a current equivalent.] Bulk Enable SaaS Enable SaaS mode for multiple locations with support for both SaaS v1 and v2 Endpoint: POST /saas-api/public-api/bulk-enable-saas/{companyId} (Version header: 2021-04-15; source: saas-api.json) Requires an Agency (company-level) token.

ghl_saas_enable_location_deprecatedA

DEPRECATED per spec — superseded by POST /saas/enable-saas/{locationId}. REQUIRES AN AGENCY-LEVEL (Company) TOKEN. [DEPRECATED per official docs — prefer the documented replacement if one exists.] [LEGACY FALLBACK — this endpoint is no longer in the live v3 docs (checked 2026-10-28) but is still served under the legacy Version header. Expect removal; prefer a current equivalent.] Enable SaaS for Sub-Account (Formerly Location)

ghl_saas_get_location_subscription_deprecatedA

DEPRECATED per spec — superseded by GET /saas/get-saas-subscription/{locationId}. REQUIRES AN AGENCY-LEVEL (Company) TOKEN. [DEPRECATED per official docs — prefer the documented replacement if one exists.] [LEGACY FALLBACK — this endpoint is no longer in the live v3 docs (checked 2026-10-28) but is still served under the legacy Version header. Expect removal; prefer a current equivalent.] Get Location Subscription Details Fetch subscription details for a specific location from location metadata Endpoint: GET /saas-api/public-api/get-saas-subscription/{locationId} (Version header: 2021-04-15; source: saas-api.json) Requires an Agency (company-level) token.

ghl_saas_get_locations_by_stripe_id_deprecatedA

DEPRECATED per spec — superseded by GET /saas/locations. REQUIRES AN AGENCY-LEVEL (Company) TOKEN. [DEPRECATED per official docs — prefer the documented replacement if one exists.] [LEGACY FALLBACK — this endpoint is no longer in the live v3 docs (checked 2026-10-28) but is still served under the legacy Version header. Expect removal; prefer a current equivalent.] Get locations by stripeId with companyId Get locations by stripeCustomerId or stripeSubscriptionId with companyId Endpoint: GET /saas-api/public-api/locations (Version header: 2021-04-15; source: saas-api.json) Requires an Agency (company-level) token.

ghl_saas_pause_location_deprecatedA

DEPRECATED per spec — superseded by POST /saas/pause/{locationId}. REQUIRES AN AGENCY-LEVEL (Company) TOKEN. [DEPRECATED per official docs — prefer the documented replacement if one exists.] [LEGACY FALLBACK — this endpoint is no longer in the live v3 docs (checked 2026-10-28) but is still served under the legacy Version header. Expect removal; prefer a current equivalent.] Pause location Pause Sub account for given locationId Endpoint: POST /saas-api/public-api/pause/{locationId} (Version header: 2021-04-15; source: saas-api.json) Requires an Agency (company-level) token.

ghl_saas_get_locations_deprecatedA

DEPRECATED per spec — superseded by GET /saas/saas-locations/{companyId}. REQUIRES AN AGENCY-LEVEL (Company) TOKEN. [DEPRECATED per official docs — prefer the documented replacement if one exists.] [LEGACY FALLBACK — this endpoint is no longer in the live v3 docs (checked 2026-10-28) but is still served under the legacy Version header. Expect removal; prefer a current equivalent.] Get SaaS Locations Fetch all SaaS-activated locations for a company with pagination Endpoint: GET /saas-api/public-api/saas-locations/{companyId} (Version header: 2021-04-15; source: saas-api.json) Requires an Agency (company-level) token. Pagination params: page — pass them to page through full result sets.

ghl_saas_get_plan_deprecatedA

DEPRECATED per spec — superseded by GET /saas/saas-plan/{planId}. REQUIRES AN AGENCY-LEVEL (Company) TOKEN. [DEPRECATED per official docs — prefer the documented replacement if one exists.] [LEGACY FALLBACK — this endpoint is no longer in the live v3 docs (checked 2026-10-28) but is still served under the legacy Version header. Expect removal; prefer a current equivalent.] Get SaaS Plan Fetch a specific SaaS plan by plan ID Endpoint: GET /saas-api/public-api/saas-plan/{planId} (Version header: 2021-04-15; source: saas-api.json) Requires an Agency (company-level) token.

ghl_saas_update_rebilling_deprecatedA

DEPRECATED per spec — superseded by POST /saas/update-rebilling/{companyId}. REQUIRES AN AGENCY-LEVEL (Company) TOKEN. [DEPRECATED per official docs — prefer the documented replacement if one exists.] [LEGACY FALLBACK — this endpoint is no longer in the live v3 docs (checked 2026-10-28) but is still served under the legacy Version header. Expect removal; prefer a current equivalent.] Update Rebilling Bulk update rebilling for given locationIds Endpoint: POST /saas-api/public-api/update-rebilling/{companyId} (Version header: 2021-04-15; source: saas-api.json) Requires an Agency (company-level) token.

ghl_saas_update_saas_subscription_deprecatedA

DEPRECATED per spec — superseded by PUT /saas/update-saas-subscription/{locationId}. REQUIRES AN AGENCY-LEVEL (Company) TOKEN. NOTE: the generated name for this op was misleading ('generate_payment_link'); corrected to reflect what the op actually does (updates an existing SaaS subscription plan/pricing), matching its summary 'Update SaaS subscription'. [DEPRECATED per official docs — prefer the documented replacement if one exists.] [LEGACY FALLBACK — this endpoint is no longer in the live v3 docs (checked 2026-10-28) but is still served under the legacy Version header. Expect removal; prefer a current equivalent.] Update SaaS subscription Update SaaS subscription for given locationId and customerId Endpoint: PUT /saas-api/public-api/update-saas-subscription/{locationId} (Version header: 2021-04-15; source: saas-api.json) Requires an Agency (company-level) token.

ghl_social_get_facebook_page_groupB

Get facebook pages Endpoint: GET /social-media-posting/oauth/{locationId}/facebook/accounts/{accountId} (Version header: 2021-07-28; source: social-media-posting.json)

ghl_social_attach_facebook_page_groupC

Attach facebook pages Endpoint: POST /social-media-posting/oauth/{locationId}/facebook/accounts/{accountId} (Version header: 2021-07-28; source: social-media-posting.json)

ghl_social_get_google_locationsB

Get google business locations Endpoint: GET /social-media-posting/oauth/{locationId}/google/locations/{accountId} (Version header: 2021-07-28; source: social-media-posting.json)

ghl_social_set_google_locationsC

Set google business locations Endpoint: POST /social-media-posting/oauth/{locationId}/google/locations/{accountId} (Version header: 2021-07-28; source: social-media-posting.json)

ghl_social_get_instagram_page_groupB

Get Instagram Professional Accounts Endpoint: GET /social-media-posting/oauth/{locationId}/instagram/accounts/{accountId} (Version header: 2021-07-28; source: social-media-posting.json)

ghl_social_attach_instagram_page_groupC

Attach Instagram Professional Accounts Endpoint: POST /social-media-posting/oauth/{locationId}/instagram/accounts/{accountId} (Version header: 2021-07-28; source: social-media-posting.json)

ghl_social_get_linkedin_page_profileC

Get Linkedin pages and profile Endpoint: GET /social-media-posting/oauth/{locationId}/linkedin/accounts/{accountId} (Version header: 2021-07-28; source: social-media-posting.json)

ghl_social_attach_linkedin_page_profileC

Attach linkedin pages and profile Endpoint: POST /social-media-posting/oauth/{locationId}/linkedin/accounts/{accountId} (Version header: 2021-07-28; source: social-media-posting.json)

ghl_social_get_tiktok_business_profileA

Get Tiktok Business profile Endpoint: GET /social-media-posting/oauth/{locationId}/tiktok-business/accounts/{accountId} (Version header: 2021-07-28; source: social-media-posting.json)

ghl_social_get_tiktok_profileC

Get Tiktok profile Endpoint: GET /social-media-posting/oauth/{locationId}/tiktok/accounts/{accountId} (Version header: 2021-07-28; source: social-media-posting.json)

ghl_social_attach_tiktok_profileC

Attach Tiktok profile Endpoint: POST /social-media-posting/oauth/{locationId}/tiktok/accounts/{accountId} (Version header: 2021-07-28; source: social-media-posting.json)

ghl_social_get_twitter_profileB

[DEPRECATED per official docs — prefer the documented replacement if one exists.] Get Twitter profile

ghl_social_attach_twitter_profileA

[DEPRECATED per official docs — prefer the documented replacement if one exists.] Attach Twitter profile

ghl_user_get_by_locationA

DEPRECATED per spec — superseded by GET /users/search (v3), which supports the same locationId filter plus richer query/paging options. [DEPRECATED per official docs — prefer the documented replacement if one exists.] [LEGACY FALLBACK — this endpoint is no longer in the live v3 docs (checked 2026-10-28) but is still served under the legacy Version header. Expect removal; prefer a current equivalent.] Get User by Location Deprecated. Use GET /users/search instead. Pass locationId as a query parameter to filter results by location, along with the required companyId and other search filters as needed. Endpoint: GET /users/ (Version header: 2021-07-28; source: users.json) Requires a Sub-Account (location) token. OAuth scopes: users.readonly

ghl_ad_fb_account_deleteA

Delete ad account Remove a Facebook ad account connection from a location Endpoint: DELETE /ad-publishing/facebook/ad-accounts/{adAccountId} (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_fb_account_getB

Get ad account details Retrieve details of a specific Facebook ad account Endpoint: GET /ad-publishing/facebook/ad-accounts/{adAccountId} (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_fb_account_listB

Get ad accounts Retrieve Facebook ad accounts available for the connected user Endpoint: GET /ad-publishing/facebook/ad-accounts (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly Pagination params: limit — pass them to page through full result sets.

ghl_ad_fb_ad_duplicateB

Duplicate ad Duplicate an existing Facebook ad Endpoint: POST /ad-publishing/facebook/ads/{adId}/duplicate (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_fb_ad_pauseB

Pause ad Pause a running Facebook ad Endpoint: POST /ad-publishing/facebook/ads/{adId}/pause (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_fb_ad_resumeA

Resume ad Resume a paused Facebook ad Endpoint: POST /ad-publishing/facebook/ads/{adId}/resume (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_fb_ad_deleteA

Delete ad Delete a Facebook ad by ID Endpoint: DELETE /ad-publishing/facebook/ads/{adId} (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_fb_adset_duplicateB

Duplicate ad set Duplicate an existing Facebook ad set Endpoint: POST /ad-publishing/facebook/adsets/{adSetId}/duplicate (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_fb_adset_pauseA

Pause ad set Pause a running Facebook ad set Endpoint: POST /ad-publishing/facebook/adsets/{adSetId}/pause (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_fb_adset_resumeA

Resume ad set Resume a paused Facebook ad set Endpoint: POST /ad-publishing/facebook/adsets/{adSetId}/resume (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_fb_adset_deleteA

Delete ad set Delete a Facebook ad set by ID Endpoint: DELETE /ad-publishing/facebook/adsets/{adSetId} (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_fb_adset_upsertB

Upsert adset Create or update a Facebook ad set Endpoint: PUT /ad-publishing/facebook/adsets (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_fb_ad_upsertB

Upsert ad Create or update a Facebook ad Endpoint: PUT /ad-publishing/facebook/ads (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_fb_campaign_getA

Get campaign with linked entities Retrieve a Facebook campaign with its linked adsets and ads Endpoint: GET /ad-publishing/facebook/campaign/{campaignId} (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_fb_campaign_duplicateB

Duplicate campaign Duplicate an existing Facebook campaign Endpoint: POST /ad-publishing/facebook/campaigns/{campaignId}/duplicate (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_fb_campaign_pauseA

Pause campaign Pause a running Facebook campaign Endpoint: POST /ad-publishing/facebook/campaigns/{campaignId}/pause (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_fb_campaign_publishing_progress_getA

Get campaign publishing progress Returns Redis-backed publish progress for a campaign while it is publishing to Meta. Used by the validation funnel UI to poll step counts and completion state. Endpoint: GET /ad-publishing/facebook/campaigns/{campaignId}/publishing-progress (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_fb_campaign_publishA

Publish campaign Queue a Facebook campaign for publishing and push it live to Facebook. Publishing runs asynchronously, so the campaign comes back in the state it was queued in — publishingStatus is still DRAFT on the campaign and on every ad set and ad, and no Facebook ids are attached yet. Poll GET /facebook/campaigns/{campaignId}/publishing-progress for the outcome. Endpoint: POST /ad-publishing/facebook/campaigns/{campaignId}/publish (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_fb_campaign_resumeA

Resume campaign Resume a paused Facebook campaign Endpoint: POST /ad-publishing/facebook/campaigns/{campaignId}/resume (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_fb_campaign_deleteA

Delete campaign Delete a Facebook campaign by ID Endpoint: DELETE /ad-publishing/facebook/campaigns/{campaignId} (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_fb_campaign_upsertB

Upsert campaign Create or update a Facebook campaign Endpoint: PUT /ad-publishing/facebook/campaigns (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_fb_conversation_form_listA

Get conversation forms Retrieve Facebook conversation lead forms for a location. Without limit the response is a plain array. When limit is provided (max 100) the response is a paginated { conversationForms, paging } envelope; pass after (from paging.next) to fetch the next batch. Endpoint: GET /ad-publishing/facebook/conversation-forms (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly Pagination params: limit — pass them to page through full result sets.

ghl_ad_fb_conversation_form_createA

Create conversation form Create a Messenger conversation form. Note the created record is returned in its raw stored form rather than the shape the listing endpoint uses: the identifier comes back as _id instead of id, and the internal __v version key is included. Endpoint: POST /ad-publishing/facebook/conversation-forms (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_fb_audience_member_batch_updateA

Batch update audience members Add or remove members in bulk from a Facebook custom audience, sourced from a CSV or one or more smart lists — at least one of csvPath or smartlistIds is required. The work is queued rather than performed inline, so the acknowledgement confirms only that the job was accepted; nothing about the outcome is reported here. Unlike the single-member endpoints this one answers with { success: true } rather than a status-and-message body. Endpoint: PUT /ad-publishing/facebook/custom-audience/{customAudienceId}/member/batch (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_fb_audience_member_removeA

Remove custom audience member Remove a single contact from a Facebook custom audience. Note this DELETE takes a request body carrying locationId and contactId, rather than identifying the member through the path or query. Endpoint: DELETE /ad-publishing/facebook/custom-audience/{customAudienceId}/member (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_fb_audience_member_addA

Add custom audience member Add a single contact to a Facebook custom audience. The contact is resolved from contactId and its identifiers are hashed before being sent to Meta. Use the batch endpoint for more than one member. Endpoint: PUT /ad-publishing/facebook/custom-audience/{customAudienceId}/member (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_fb_audience_deleteA

Delete custom audience Delete a Facebook custom audience by ID Endpoint: DELETE /ad-publishing/facebook/custom-audience/{customAudienceId} (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_fb_audience_getA

Get custom audience by ID Retrieve one custom audience with its full detail. Returns more than the listing endpoint: Meta adds the fields relevant to the audience subtype (retentionDays and customerFileSource for customer lists, rule and pixelId for website audiences, lookalikeSpec for lookalikes), and this service appends extras describing the local smart-list or CSV source when the audience is a user-provided customer list. Endpoint: GET /ad-publishing/facebook/custom-audience/{customAudienceId} (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_fb_audience_updateA

Update custom audience Rename a Facebook custom audience or change its description. Only those two fields can be updated; membership is changed through the member endpoints. The audience is also queued for reprocessing, so the acknowledgement does not mean downstream state has caught up. Endpoint: PUT /ad-publishing/facebook/custom-audience/{customAudienceId} (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_fb_audience_listA

Get custom audiences Retrieve Facebook custom audiences for a location. Without limit the response is a plain array. When limit is provided (max 100) the response is a paginated { customAudiences, paging } envelope; pass after (from paging.next) to fetch the next batch. By default each item is returned in full; pass projection (comma-separated, dot-notation for nested fields, e.g. ?projection=id,name,dataSource.type) to return only the requested fields — any value outside the known field set is rejected. Endpoint: GET /ad-publishing/facebook/custom-audience (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly Pagination params: limit — pass them to page through full result sets.

ghl_ad_fb_entity_getA

Get entities Retrieve campaigns, ad sets, or ads for a location. entityType selects which, and each returns a { data } envelope whose item shape differs — the id key is campaignId, adSetId, or adId respectively, and the status fields differ too: campaigns carry both status and effectiveStatus, ad sets only effectiveStatus, and ads only status. next is returned only when the branch pages through Meta, so treat its absence as the end of the results rather than assuming a cursor. For CAMPAIGN, type=INTEGRATION queries Meta while type=AD_MANAGER reads campaigns this service published, filtered to PAUSED and PUBLISHED. ADSET requires campaignId; AD accepts adSetId for a single ad set or campaignId to page across the campaign. Endpoint: GET /ad-publishing/facebook/entity (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_fb_integration_deleteA

Delete Facebook integration Remove the Facebook ad integration from a location Endpoint: DELETE /ad-publishing/facebook/integration (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_fb_integration_getA

Get Facebook integration Retrieve the Facebook ad integration details for a location Endpoint: GET /ad-publishing/facebook/integration (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_fb_integration_createA

Create Facebook integration Create a Facebook ad integration for a location with page and ad account Endpoint: POST /ad-publishing/facebook/integration (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_fb_lead_form_getA

Get lead form by ID Retrieve a lead form by id. Pass isDraft=true to read an unpublished local draft instead, in which case leadFormId accepts either the bare id or the draft_-prefixed form the listing endpoint reports. The two branches return different shapes, and neither matches the shape the listing endpoint returns for the same form: the published branch carries the full Meta definition (context card, thank-you page, legal content) but no status, createdTime, or pageId, while the draft branch returns the stored document verbatim under _id. Endpoint: GET /ad-publishing/facebook/lead-form/{leadFormId} (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_fb_current_user_getA

Get current Facebook user Retrieve the authenticated Facebook user profile for a location Endpoint: GET /ad-publishing/facebook/me (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_fb_page_lead_form_listA

Get page lead forms Retrieve lead gen forms for a specific Facebook page (published + drafts), sorted newest-first by createdTime. By default each form is returned in full (including its questions) as a plain array; pass projection (comma-separated) to return only the requested fields — any value outside the known field set is rejected. Pass limit (max 100) for a { forms, paging } envelope; use after (from paging.next) to fetch the next batch. Endpoint: GET /ad-publishing/facebook/page/{pageId}/forms (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly Pagination params: limit — pass them to page through full result sets.

ghl_ad_fb_page_lead_form_createA

Create page lead form Create a lead gen form. With isDraft: true the form is stored locally and returned as a draft; without it the form is published to Facebook and the Meta record is returned. The two responses share almost no fields. Publishing enforces at least one question and a complete thankYouPage (title, body, buttonText) where a draft save enforces neither. Pass draftFormId when publishing an existing draft to have it deleted afterwards — either the bare id or the draft_-prefixed form is accepted, and cleanup failures are logged rather than surfaced. Endpoint: POST /ad-publishing/facebook/page/{pageId}/forms (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_fb_page_instagram_account_listB

Get Instagram accounts for page Retrieve Instagram accounts linked to a specific Facebook page Endpoint: GET /ad-publishing/facebook/page/{pageId}/instagram (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_fb_page_set_defaultB

Set default page Set the default Facebook page for a location Endpoint: PUT /ad-publishing/facebook/page/default (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_fb_page_deleteA

Delete page connection Remove a Facebook page connection from a location. Deprecated: use DELETE /ad-publishing/facebook/pages/{pageId} with header version: v4. Endpoint: DELETE /ad-publishing/facebook/page (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_fb_page_listA

Get Facebook pages Retrieve Facebook pages for the connected account. Without limit the response is an array of pages (this array response will soon be deprecated — migrate to the paginated form). When limit is provided the response is a paginated { pages, paging } envelope; pass after (from paging.next) to fetch the next batch. Endpoint: GET /ad-publishing/facebook/pages (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly Pagination params: limit — pass them to page through full result sets.

ghl_ad_fb_pixel_listA

Get conversion pixels Retrieve Facebook conversion pixels for a location. channel selects between two unrelated behaviours. For FACEBOOK (the default) the response is { items, total }, or a paginated { items, paging } envelope when limit (max 100) is given — pass after from paging.next for the next batch — and projection (comma-separated, from createdAt, fbIsCrmPixel, fbPixelCode, fbPixelId, name, type) narrows each item. For IG the response is instead a bare array of Instagram datasets carrying only an id, and limit, after, and projection are ignored. Endpoint: GET /ad-publishing/facebook/pixels (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly Pagination params: limit — pass them to page through full result sets.

ghl_ad_fb_pixel_upsertA

Upsert conversion pixel Create a Facebook conversion pixel, or rename an existing one by passing conversionPixelId. The two paths acknowledge differently: a create returns the new id, a rename returns only { success: true }. Renaming is the only update supported, and it rejects type: INSTAGRAM_DM. Creating an INSTAGRAM_DM dataset requires igUserId and fails if one already exists for that account. Endpoint: PUT /ad-publishing/facebook/pixels (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_fb_campaign_reporting_getA

Get campaign reporting Retrieve reporting for one campaign as a flat object, not the { grouped, totals } envelope the account-level report uses. Merges the locally stored campaign, Meta insights for the window, and CDP-attributed contacts. The campaign must be published — one without an fbCampaignId is rejected. Note results.lead (Meta lead actions) and leads (CDP attributed contacts) measure different things and routinely disagree. Endpoint: GET /ad-publishing/facebook/reporting/campaign/{campaignId} (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_fb_reporting_listA

Get reporting list Retrieve campaigns, ad sets, or ads with their reporting metrics. listType selects the entity and changes the item shape; adsets and ads additionally require campaignId. Entities Meta has no insights for are still returned, padded with a fixed zero row that carries fewer fields than a real one. Note none is accepted by validation but has no handler and fails with a 409. Deprecated: use GET /ad-publishing/facebook/reporting/rows with header version: v4. Endpoint: GET /ad-publishing/facebook/reporting/list (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_fb_reporting_getA

Get reporting data Retrieve aggregated Facebook ad reporting metrics for a location. grouped holds one row per groupBy period, or a single row covering the whole range when groupBy is omitted, and totals aggregates across them. Both objects only carry the metrics named in fields. Be aware that ratio metrics (cpm, ctr, frequency) are summed rather than weighted in totals, and that cost_per_conversion and cost_per_result are placeholders that always read 0 — their real values live under costPerConversion and costPerResult. Endpoint: GET /ad-publishing/facebook/reporting (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_fb_targeting_searchA

Search targeting options Search Facebook targeting options for ad set audience building. type selects which taxonomy is searched and determines the response shape: geolocation returns places, interest returns interests, behaviours, and demographics, and language returns locales. Geolocation and interest results are passed through from Facebook, so their fields are snake_case. Endpoint: GET /ad-publishing/facebook/targeting/search (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_google_account_deleteA

Delete ad account Remove a Google Ads account connection from a location Endpoint: DELETE /ad-publishing/google/ad-accounts/{adAccountId} (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_google_account_getA

Get ad account details Retrieve details of a specific Google Ads account Endpoint: GET /ad-publishing/google/ad-accounts/{adAccountId} (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_google_account_listB

Get Google ad accounts Retrieve Google Ads accounts available for the connected user Endpoint: GET /ad-publishing/google/ad-accounts (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_google_get_publishing_progressA

Get ad publishing progress Returns Redis-backed publish progress for a Google campaign while it is publishing. Used by the publish progress UI to poll step counts and completion state. Endpoint: GET /ad-publishing/google/ads/{adId}/publishing-progress (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_google_campaign_publishB

Publish ad Publish a Google ad and push it live Endpoint: POST /ad-publishing/google/ads/{adId}/publish (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_google_campaign_getB

Get Google campaign by ID Retrieve a specific Google Ads campaign by ID Endpoint: GET /ad-publishing/google/ads/{adId} (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_google_campaign_upsertB

Upsert Google campaign Create or update a full Google Ads campaign structure Endpoint: PUT /ad-publishing/google/ads (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_google_asset_listA

Get assets Retrieve Google Ads creative assets for a location. Without limit the response is a plain array of assets. When limit is provided (max 100, default 100) the response is a paginated { assets, paging } envelope; pass pageToken (from paging.next) to fetch the next batch. Endpoint: GET /ad-publishing/google/assets (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly Pagination params: limit — pass them to page through full result sets.

ghl_ad_google_asset_upsertB

Upsert assets Create or update Google Ads creative assets Endpoint: POST /ad-publishing/google/assets (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_google_audience_getA

Get audience by ID Retrieve a specific Google Ads combined audience by ID Endpoint: GET /ad-publishing/google/audiences/{audienceId} (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_google_audience_listA

Get audiences Retrieve Google Ads combined audiences for a location. Without limit the response is a plain array. When limit is provided (max 100, default 100) the response is a paginated { audiences, paging } envelope; pass pageToken (from paging.next) to fetch the next batch. Endpoint: GET /ad-publishing/google/audiences (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly Pagination params: limit — pass them to page through full result sets.

ghl_ad_google_audience_upsertB

Upsert audience Create or update a Google Ads combined audience Endpoint: PUT /ad-publishing/google/audiences (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_google_conversion_goal_listA

Get conversion goals Retrieve Google Ads conversion goals for a location. Without limit the response is a plain array. When limit is provided (max 100, default 100) the response is a paginated { conversionGoals, paging } envelope; pass pageToken (from paging.next) to fetch the next batch. Endpoint: GET /ad-publishing/google/conversion-goals (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly Pagination params: limit — pass them to page through full result sets.

ghl_ad_google_conversion_deleteA

Delete conversion Delete a Google Ads conversion action by ID Endpoint: DELETE /ad-publishing/google/conversions/{conversionId} (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_google_conversion_getA

Get conversion by ID Retrieve a specific Google Ads conversion action by ID Endpoint: GET /ad-publishing/google/conversions/{conversionId} (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_google_conversion_listA

Get conversions Retrieve Google Ads conversion actions for a location. The response shape is selected by type. When type is AD_MANAGER: without limit a plain array of full conversion actions, and with limit (max 100, default 100) a paginated { conversions, paging } envelope — pass pageToken (from paging.next) for the next batch. When type is omitted or AD_WORDS, a different, minimal snake_case projection is returned and limit, pageToken, startDate, endDate, conversionType and category are all ignored. Endpoint: GET /ad-publishing/google/conversions (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly Pagination params: limit — pass them to page through full result sets.

ghl_ad_google_conversion_upsertA

Upsert conversion Create or update a Google Ads conversion action Endpoint: PUT /ad-publishing/google/conversions (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_google_entity_getB

Get entities Retrieve Google campaigns, ad groups, or ads based on entity type Endpoint: GET /ad-publishing/google/entity (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_google_integration_getA

Get Google integration Retrieve the Google Ads integration details for a location Endpoint: GET /ad-publishing/google/integration (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_google_integration_createB

Create Google integration Create a Google Ads integration for a location Endpoint: POST /ad-publishing/google/integration (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_google_keyword_ideas_getB

Get keyword ideas Retrieve keyword suggestions for Google Ads campaigns Endpoint: POST /ad-publishing/google/keyword-ideas (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_google_current_user_getA

Get current Google user Retrieve the authenticated Google user info for a location Endpoint: GET /ad-publishing/google/me (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_google_campaign_reporting_getB

Get campaign reporting Retrieve reporting metrics for a specific Google campaign Endpoint: GET /ad-publishing/google/reporting/campaign/{campaignId} (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_google_reporting_listA

Get reporting list Retrieve a list of Google campaigns or ad groups with reporting data. Deprecated: use GET /ad-publishing/google/reporting/rows with header version: v4. Endpoint: GET /ad-publishing/google/reporting/list (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_google_reporting_getB

Get reporting data Retrieve aggregated Google Ads reporting metrics for a location Endpoint: GET /ad-publishing/google/reporting (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_google_segment_deleteB

Delete segment Delete a Google Ads audience segment by ID Endpoint: DELETE /ad-publishing/google/segments/{segmentId} (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_google_segment_getA

Get segment by ID Retrieve a specific Google Ads audience segment by ID Endpoint: GET /ad-publishing/google/segments/{segmentId} (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_google_segment_offline_job_createB

Create offline user list job Create a job to upload users to a Google customer match list Endpoint: POST /ad-publishing/google/segments/offline-user-list-job (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_google_segment_listA

Get segments Retrieve Google Ads audience segments for a location. Without limit the response is a plain array. When limit is provided (max 100, default 100) the response is a paginated { segments, paging } envelope; pass pageToken (from paging.next) to fetch the next batch. Endpoint: GET /ad-publishing/google/segments (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly Pagination params: limit — pass them to page through full result sets.

ghl_ad_google_segment_upsertB

Upsert segment Create or update a Google Ads audience segment Endpoint: PUT /ad-publishing/google/segments (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_google_target_interest_listA

Get target interests Retrieve affinity and in-market audience options for Google Ads targeting. Without limit the response is a plain array of root interests (each with a nested children tree). When limit is provided (max 100) the response is a paginated { targetInterests, paging } envelope — a page counts root interests; pass pageToken (from paging.next) to fetch the next batch. By default each node is returned in full; pass projection (comma-separated, e.g. ?projection=name,userInterestId,children) to return only the requested fields — selecting children prunes the whole tree recursively with the same selection, and any value outside the known field set is rejected. Endpoint: GET /ad-publishing/google/target-interests (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly Pagination params: limit — pass them to page through full result sets.

ghl_ad_google_targeting_searchA

Search targeting options Search Google geo-locations for ad targeting Endpoint: GET /ad-publishing/google/targeting/search (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_li_lead_form_createA

Create lead form Create a new LinkedIn lead gen form for an ad account. Deprecated: use POST /ad-publishing/linkedin/accounts/{accountId}/form with header version: v4. Endpoint: POST /ad-publishing/linkedin/{accountId}/form (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_li_lead_form_listA

Get lead forms Retrieve LinkedIn lead gen forms for an ad account. By default each form is returned in full as a plain array; pass projection (comma-separated, dot-notation for nested fields) to return only the requested fields — any value outside the known field set is rejected. When limit is provided (max 100) the response is a paginated { leadForms, paging } envelope; pass pageToken (from paging.next) to fetch the next batch. Deprecated: use GET /ad-publishing/linkedin/accounts/{accountId}/forms with header version: v4. Endpoint: GET /ad-publishing/linkedin/{accountId}/forms (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly Pagination params: limit — pass them to page through full result sets.

ghl_ad_li_ad_status_updateA

Update ad status Pause or resume a LinkedIn ad, campaign, or ad group. Deprecated: use PATCH /ad-publishing/linkedin/ads/{adId}/status with header version: v4. Endpoint: PATCH /ad-publishing/linkedin/{adId}/status (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_li_account_deleteA

Delete ad account Remove a LinkedIn ad account connection from a location. Deprecated: use DELETE /ad-publishing/linkedin/ad-accounts/{adAccountId} with header version: v4. Endpoint: DELETE /ad-publishing/linkedin/ad-account (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_li_account_getA

Get ad account details Retrieve details of a specific LinkedIn ad account. Deprecated: use GET /ad-publishing/linkedin/ad-accounts/{adAccountId} with header version: v4. Endpoint: GET /ad-publishing/linkedin/ad-account (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_li_account_listA

Get LinkedIn ad accounts Retrieve LinkedIn Ads accounts available for the connected user Endpoint: GET /ad-publishing/linkedin/ad-accounts (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_li_campaign_group_publishB

Publish ad campaign group Publish a LinkedIn ad campaign group and push it live Endpoint: POST /ad-publishing/linkedin/ads/{adId}/publish (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_li_campaign_group_getA

Get ad campaign group Retrieve a LinkedIn ad campaign group by ID Endpoint: GET /ad-publishing/linkedin/ads/{adId} (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_li_campaign_group_upsertA

Upsert ad campaign group Create or update a LinkedIn ad campaign group with campaigns and ads Endpoint: PUT /ad-publishing/linkedin/ads (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_li_integration_getA

Get LinkedIn integration Retrieve the LinkedIn Ads integration details for a location Endpoint: GET /ad-publishing/linkedin/integration (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_li_integration_createA

Create LinkedIn integration Create a LinkedIn Ads integration for a location with ad account details Endpoint: POST /ad-publishing/linkedin/integration (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.write

ghl_ad_li_current_user_getA

Get current LinkedIn user Retrieve the authenticated LinkedIn user info for a location Endpoint: GET /ad-publishing/linkedin/me (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_li_campaign_group_reporting_getA

Get campaign group reporting Retrieve reporting metrics for a specific LinkedIn campaign group Endpoint: GET /ad-publishing/linkedin/reporting/campaign-group/{campaignGroupId} (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_li_reporting_listA

Get reporting list Retrieve a list of LinkedIn campaigns or campaign groups with reporting data. Deprecated: use GET /ad-publishing/linkedin/reporting/rows with header version: v4. Endpoint: GET /ad-publishing/linkedin/reporting/list (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_li_reporting_getA

Get ad analytics Retrieve LinkedIn Ads analytics data with configurable pivot and time grouping Endpoint: GET /ad-publishing/linkedin/reporting (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_ad_li_targeting_searchA

Search targeting options Search LinkedIn targeting facets such as locations, industries, and job titles Endpoint: GET /ad-publishing/linkedin/targeting/search (Version header: v3; source: v3/ad-publishing-v3.json) OAuth scopes: adPublishing.readonly

ghl_affiliate_mark_payout_method_primaryA

Mark Payout Method As Primary Make this payout method the one payouts default to. Any other method stops being primary. Endpoint: PATCH /affiliate-manager/{locationId}/affiliate/{affiliateId}/payout-method/{payoutMethodId}/primary (Version header: v3; source: v3/affiliate-manager-v3.json) Requires a Sub-Account (location) token. OAuth scopes: affiliate-manager.write

ghl_affiliate_delete_payout_methodA

Delete Payout Method Delete a payout method. The primary method cannot be deleted while the affiliate holds more than one. Endpoint: DELETE /affiliate-manager/{locationId}/affiliate/{affiliateId}/payout-method/{payoutMethodId} (Version header: v3; source: v3/affiliate-manager-v3.json) Requires a Sub-Account (location) token. OAuth scopes: affiliate-manager.write

ghl_affiliate_update_payout_methodA

Update Payout Method Replace the stored details of a payout method. The payout method type cannot be changed, and the method must belong to the affiliate named in the path. Endpoint: PUT /affiliate-manager/{locationId}/affiliate/{affiliateId}/payout-method/{payoutMethodId} (Version header: v3; source: v3/affiliate-manager-v3.json) Requires a Sub-Account (location) token. OAuth scopes: affiliate-manager.write

ghl_affiliate_list_payout_methodsA

List Payout Methods List the payout methods stored for an affiliate. Bank account values are returned as their last four characters only. Endpoint: GET /affiliate-manager/{locationId}/affiliate/{affiliateId}/payout-method (Version header: v3; source: v3/affiliate-manager-v3.json) Requires a Sub-Account (location) token. OAuth scopes: affiliate-manager.readonly Pagination params: skip, limit — pass them to page through full result sets.

ghl_affiliate_create_payout_methodA

Create Payout Method Store a payout method for an affiliate. An affiliate can hold one PayPal and one bank method; the first method stored becomes the primary one. Bank fields are validated against the requirements of the account country. Endpoint: POST /affiliate-manager/{locationId}/affiliate/{affiliateId}/payout-method (Version header: v3; source: v3/affiliate-manager-v3.json) Requires a Sub-Account (location) token. OAuth scopes: affiliate-manager.write

ghl_affiliate_delete_customerA

Delete customer Delete a lead or customer for an affiliate. Endpoint: DELETE /affiliate-manager/{locationId}/affiliates/{affiliateId}/customer/{customerId} (Version header: v3; source: v3/affiliate-manager-v3.json) Requires a Sub-Account (location) token. OAuth scopes: affiliate-manager.write

ghl_affiliate_update_customer_stateA

Update customer state Update the disabled state of a customer for an affiliate. Endpoint: PATCH /affiliate-manager/{locationId}/affiliates/{affiliateId}/customers/{customerId}/state (Version header: v3; source: v3/affiliate-manager-v3.json) Requires a Sub-Account (location) token. OAuth scopes: affiliate-manager.write

ghl_affiliate_list_customersA

List customers Retrieve the list of customers for an affiliate. Endpoint: GET /affiliate-manager/{locationId}/affiliates/{affiliateId}/customers (Version header: v3; source: v3/affiliate-manager-v3.json) Requires a Sub-Account (location) token. OAuth scopes: affiliate-manager.readonly Pagination params: skip, limit — pass them to page through full result sets.

ghl_affiliate_create_customer_leadA

Create customer lead Create or update a lead for an affiliate customer. Endpoint: POST /affiliate-manager/{locationId}/affiliates/{affiliateId}/lead/create (Version header: v3; source: v3/affiliate-manager-v3.json) Requires a Sub-Account (location) token. OAuth scopes: affiliate-manager.write

ghl_affiliate_validate_customer_leadA

Validate customer lead Check whether a lead already exists for an affiliate customer. Endpoint: GET /affiliate-manager/{locationId}/affiliates/{affiliateId}/lead/validate (Version header: v3; source: v3/affiliate-manager-v3.json) Requires a Sub-Account (location) token. OAuth scopes: affiliate-manager.readonly

ghl_affiliate_update_statusA

Update Affiliate Status Activate or deactivate an affiliate. Sending the same value again leaves the affiliate unchanged. Endpoint: PUT /affiliate-manager/{locationId}/affiliates/{affiliateId}/status (Version header: v3; source: v3/affiliate-manager-v3.json) Requires a Sub-Account (location) token. OAuth scopes: affiliate-manager.write

ghl_affiliate_upload_tax_formA

Upload affiliate tax form Upload a W-8 or W-9 document for an affiliate. Send the document as multipart/form-data; the storage location is assigned by the server. Endpoint: POST /affiliate-manager/{locationId}/affiliates/{affiliateId}/tax-form (Version header: v3; source: v3/affiliate-manager-v3.json) Requires a Sub-Account (location) token. OAuth scopes: affiliate-manager.write

ghl_affiliate_getA

Get Affiliate Retrieve a single affiliate by id for a location. Endpoint: GET /affiliate-manager/{locationId}/affiliates/{affiliateId} (Version header: v3; source: v3/affiliate-manager-v3.json) OAuth scopes: affiliate-manager.readonly

ghl_affiliate_updateA

Update Affiliate Replace an affiliate for a location. Fields omitted from the body are cleared, so send the complete affiliate. Endpoint: PUT /affiliate-manager/{locationId}/affiliates/{affiliateId} (Version header: v3; source: v3/affiliate-manager-v3.json) Requires a Sub-Account (location) token. OAuth scopes: affiliate-manager.write

ghl_affiliate_listA

List Affiliates Retrieve the list of affiliates for a location. Endpoint: GET /affiliate-manager/{locationId}/affiliates (Version header: v3; source: v3/affiliate-manager-v3.json) OAuth scopes: affiliate-manager.readonly Pagination params: skip, limit — pass them to page through full result sets.

ghl_affiliate_createA

Create Affiliate Create an affiliate for a location. An affiliate already registered with the same email in this location is updated instead of duplicated. Endpoint: POST /affiliate-manager/{locationId}/affiliates (Version header: v3; source: v3/affiliate-manager-v3.json) Requires a Sub-Account (location) token. OAuth scopes: affiliate-manager.write

ghl_affiliate_get_campaignA

Get Campaign Retrieve a single affiliate campaign by id for a location. Endpoint: GET /affiliate-manager/{locationId}/campaigns/{campaignId} (Version header: v3; source: v3/affiliate-manager-v3.json) Requires a Sub-Account (location) token. OAuth scopes: affiliate-manager.readonly

ghl_affiliate_list_campaignsA

List Campaigns Retrieve the list of affiliate campaigns for a location. Endpoint: GET /affiliate-manager/{locationId}/campaigns (Version header: v3; source: v3/affiliate-manager-v3.json) Requires a Sub-Account (location) token. OAuth scopes: affiliate-manager.readonly Pagination params: skip, limit — pass them to page through full result sets.

ghl_affiliate_deny_commissionA

Deny commission Deny a commission and move its payout to denied status. Endpoint: PUT /affiliate-manager/{locationId}/commission/{commissionId}/deny (Version header: v3; source: v3/affiliate-manager-v3.json) Requires a Sub-Account (location) token. OAuth scopes: affiliate-manager.write

ghl_affiliate_update_commission_statusA

Update commission status Update the status of a commission and its associated payout. Endpoint: PUT /affiliate-manager/{locationId}/commission/{commissionId}/status (Version header: v3; source: v3/affiliate-manager-v3.json) Requires a Sub-Account (location) token. OAuth scopes: affiliate-manager.write

ghl_affiliate_delete_commissionA

Delete commission Delete a commission and update its associated payout. Endpoint: DELETE /affiliate-manager/{locationId}/commission/{commissionId} (Version header: v3; source: v3/affiliate-manager-v3.json) Requires a Sub-Account (location) token. OAuth scopes: affiliate-manager.write

ghl_affiliate_create_commissionA

Create commission Create a manual commission for a customer. Endpoint: POST /affiliate-manager/{locationId}/commission (Version header: v3; source: v3/affiliate-manager-v3.json) Requires a Sub-Account (location) token. OAuth scopes: affiliate-manager.write

ghl_affiliate_commission_listA

List Commissions Retrieve the list of commissions for a location. Endpoint: GET /affiliate-manager/{locationId}/commissions (Version header: v3; source: v3/affiliate-manager-v3.json) OAuth scopes: affiliate-manager.readonly Pagination params: skip, limit — pass them to page through full result sets.

ghl_affiliate_list_country_bank_mappingsA

List Country Bank Mappings List the bank fields each supported country requires, for building a bank payout method. This is shared reference data, identical for every location. Endpoint: GET /affiliate-manager/{locationId}/country-bank-mapping (Version header: v3; source: v3/affiliate-manager-v3.json) Requires a Sub-Account (location) token. OAuth scopes: affiliate-manager.readonly

ghl_affiliate_delete_mediaA

Delete affiliate media Delete a media file or folder for a location. Endpoint: DELETE /affiliate-manager/{locationId}/media/{mediaId} (Version header: v3; source: v3/affiliate-manager-v3.json) Requires a Sub-Account (location) token. OAuth scopes: affiliate-manager.write

ghl_affiliate_update_mediaA

Update affiliate media Update a media file or folder for a location. Endpoint: PUT /affiliate-manager/{locationId}/media/{mediaId} (Version header: v3; source: v3/affiliate-manager-v3.json) Requires a Sub-Account (location) token. OAuth scopes: affiliate-manager.write

ghl_affiliate_list_mediaA

List affiliate media Retrieve media files and folders for a location. Endpoint: GET /affiliate-manager/{locationId}/media (Version header: v3; source: v3/affiliate-manager-v3.json) Requires a Sub-Account (location) token. OAuth scopes: affiliate-manager.readonly Pagination params: skip, limit — pass them to page through full result sets.

ghl_affiliate_payout_listA

List Payouts Retrieve the list of payouts for a location. Endpoint: GET /affiliate-manager/{locationId}/payouts (Version header: v3; source: v3/affiliate-manager-v3.json) OAuth scopes: affiliate-manager.readonly Pagination params: skip, limit — pass them to page through full result sets.

ghl_affiliate_move_campaignA

Move Affiliate To Campaign Move an affiliate from one campaign to another. The target campaign must be live and belong to the same location, and the affiliate must not already be enrolled in it. Endpoint: POST /affiliate-manager/affiliate-campaign/{locationId}/affiliate/{affiliateId}/move-campaign (Version header: v3; source: v3/affiliate-manager-v3.json) Requires a Sub-Account (location) token. OAuth scopes: affiliate-manager.write

ghl_affiliate_update_referral_idA

Update Affiliate Referral Id Set the referral id an affiliate is tracked by on a campaign. The referral link is rebuilt around the new id, and the id must be unused across the location. Endpoint: PUT /affiliate-manager/affiliate-campaign/{locationId}/affiliate/{affiliateId}/referral-id (Version header: v3; source: v3/affiliate-manager-v3.json) Requires a Sub-Account (location) token. OAuth scopes: affiliate-manager.write

ghl_affiliate_update_suspensionA

Update Affiliate Suspension Suspend or reinstate an affiliate on a campaign. Suspending cancels their pending and denied payouts, commissions and transactions; reinstating returns cancelled ones to pending. Endpoint: PUT /affiliate-manager/affiliate-campaign/{locationId}/campaign/{campaignId}/affiliate/{affiliateId}/suspension (Version header: v3; source: v3/affiliate-manager-v3.json) Requires a Sub-Account (location) token. OAuth scopes: affiliate-manager.write

ghl_affiliate_validate_referral_idA

Validate Referral Id Check whether a referral id is free to use. Referral ids are unique across a location, so a taken id reports as unavailable even when it belongs to a different campaign. Endpoint: GET /affiliate-manager/affiliate-campaign/{locationId}/referral-id/validate (Version header: v3; source: v3/affiliate-manager-v3.json) Requires a Sub-Account (location) token. OAuth scopes: affiliate-manager.readonly

ghl_agent_studio_executeA

Execute Agent Executes the specified agent and returns a non-streaming JSON response with the complete agent output. The agent must be in active status and belong to the specified location. locationId is required in the request body.

Session Management:

  • For the first message in a new session, do not include the executionId in the request payload.

  • The API will return an executionId along with the agent response, which uniquely identifies this conversation session.

  • To continue the conversation within the same session, include the executionId from the previous response in subsequent requests. This allows the agent to maintain conversation context and history across multiple interactions. Endpoint: POST /agent-studio/agent/{agentId}/execute (Version header: v3; source: v3/agent-studio-v3.json) Requires a Sub-Account (location) token. OAuth scopes: agent-studio.write

ghl_agent_studio_deleteA

Delete Agent Deletes an agent and all its versions. Endpoint: DELETE /agent-studio/agent/{agentId} (Version header: v3; source: v3/agent-studio-v3.json) Requires a Sub-Account (location) token. OAuth scopes: agent-studio.write

ghl_agent_studio_get_by_idA

Get Agent Gets a specific agent by its ID for the specified location with all its versions. Returns complete agent metadata and all non-deleted versions (draft, staging, production). locationId is required parameter. The agent must have active status. Endpoint: GET /agent-studio/agent/{agentId} (Version header: v3; source: v3/agent-studio-v3.json) Requires a Sub-Account (location) token. OAuth scopes: agent-studio.readonly

ghl_agent_studio_update_metadataA

Update Agent Metadata Updates agent metadata such as name, description, and status. Endpoint: PATCH /agent-studio/agent/{agentId} (Version header: v3; source: v3/agent-studio-v3.json) Requires a Sub-Account (location) token. OAuth scopes: agent-studio.write

ghl_agent_studio_promote_and_publishB

Promote to Production Promotes a draft version to production. Endpoint: POST /agent-studio/agent/versions/{versionId}/publish (Version header: v3; source: v3/agent-studio-v3.json) Requires a Sub-Account (location) token. OAuth scopes: agent-studio.write

ghl_agent_studio_update_versionA

Update Agent Updates a specific agent version by versionId. Supports updating nodes, edges, variables, and configuration. Endpoint: PATCH /agent-studio/agent/versions/{versionId} (Version header: v3; source: v3/agent-studio-v3.json) Requires a Sub-Account (location) token. OAuth scopes: agent-studio.write

ghl_agent_studio_listA

Lists agents (paginated via limit/offset) — not a get-by-id lookup. List Agents Lists all active agents for the specified location. locationId is required parameter to ensure optimal performance. Supports pagination using limit and offset. Optionally filter by isPublished=true to return only agents with a published production version. Endpoint: GET /agent-studio/agent (Version header: v3; source: v3/agent-studio-v3.json) Requires a Sub-Account (location) token. OAuth scopes: agent-studio.readonly Pagination params: limit, offset — pass them to page through full result sets.

ghl_agent_studio_createA

Create Agent Creates a new agent with staging version. The agent will be created with an initial staging version that can later be promoted to production. Endpoint: POST /agent-studio/agent (Version header: v3; source: v3/agent-studio-v3.json) Requires a Sub-Account (location) token. OAuth scopes: agent-studio.write

ghl_agent_studio_execute_managedA

Execute a published Managed Agent Runs one JSON turn against the published production snapshot. Omit sessionId on the first turn and pass the returned sessionId on subsequent turns. Reuse the same Idempotency-Key only when retrying the exact same logical turn. For a 429 response, retry that key only when retryable is true and Retry-After is present. Endpoint: POST /agent-studio/managed-agents/{managedAgentId}/execute (Version header: v3; source: v3/agent-studio-v3.json) Requires a Sub-Account (location) token. OAuth scopes: managed-agents.write

ghl_agent_studio_get_managedA

Get a published Managed Agent Returns public metadata for a published production Managed Agent. Unknown, unpublished, and cross-location identifiers return 404. Endpoint: GET /agent-studio/managed-agents/{managedAgentId} (Version header: v3; source: v3/agent-studio-v3.json) Requires a Sub-Account (location) token. OAuth scopes: managed-agents.readonly

ghl_agent_studio_list_managedA

List published Managed Agents Returns only Managed Agents with a published production version in the authorized sub-account. Endpoint: GET /agent-studio/managed-agents (Version header: v3; source: v3/agent-studio-v3.json) Requires a Sub-Account (location) token. OAuth scopes: managed-agents.readonly Pagination params: skip, limit — pass them to page through full result sets.

ghl_agent_studio_execute_deprecatedA

Deprecated per official spec — use ghl_agent_studio_execute (POST /agent-studio/agent/{agentId}/execute) instead. [DEPRECATED per official docs — prefer the documented replacement if one exists.] Execute Agent (Deprecated) Deprecated endpoint - use POST /agent/:agentId/execute instead.

Executes the specified agent and returns a non-streaming JSON response with the complete agent output. The agent must be in active status and belong to the specified location. locationId is required in the request body.

Session Management:

  • For the first message in a new session, do not include the executionId in the request payload.

  • The API will return an executionId along with the agent response, which uniquely identifies this conversation session.

  • To continue the conversation within the same session, include the executionId from the previous response in subsequent requests. Endpoint: POST /agent-studio/public-api/agents/{agentId}/execute (Version header: v3; source: v3/agent-studio-v3.json) Requires a Sub-Account (location) token. OAuth scopes: agent-studio.write

ghl_agent_studio_get_by_id_deprecatedA

Deprecated per official spec — use ghl_agent_studio_get_by_id (GET /agent-studio/agent/{agentId}) instead. [DEPRECATED per official docs — prefer the documented replacement if one exists.] Get Agent (Deprecated) Deprecated endpoint - use GET /agent/:agentId instead.

Gets a specific agent by its ID for the specified location with all its versions. locationId is required parameter. The agent must have active status. Endpoint: GET /agent-studio/public-api/agents/{agentId} (Version header: v3; source: v3/agent-studio-v3.json) Requires a Sub-Account (location) token. OAuth scopes: agent-studio.readonly

ghl_agent_studio_list_deprecatedA

Deprecated per official spec — use ghl_agent_studio_list (GET /agent-studio/agent) instead. [DEPRECATED per official docs — prefer the documented replacement if one exists.] List Agents (Deprecated) Deprecated endpoint - use GET /agent instead.

Lists all active agents that have a published production version for the specified location. locationId is required parameter. Supports pagination using limit and offset. Endpoint: GET /agent-studio/public-api/agents (Version header: v3; source: v3/agent-studio-v3.json) Requires a Sub-Account (location) token. OAuth scopes: agent-studio.readonly Pagination params: limit, offset — pass them to page through full result sets.

ghl_association_deleteB

Delete Association Delete USER_DEFINED Association By Id, deleting an association will also all the relations for that association Endpoint: DELETE /associations/{associationId} (Version header: v3; source: v3/associations-v3.json) OAuth scopes: associations.write

ghl_association_get_by_idA

Get association by ID Using this api you can get SYSTEM_DEFINED / USER_DEFINED association by id Endpoint: GET /associations/{associationId} (Version header: v3; source: v3/associations-v3.json) OAuth scopes: associations.readonly

ghl_association_updateB

Update Association By Id Update Association , Allows you to update labels of an associations. Documentation Link - https://doc.clickup.com/8631005/d/h/87cpx-293776/cd0f4122abc04d3 Endpoint: PUT /associations/{associationId} (Version header: v3; source: v3/associations-v3.json) OAuth scopes: associations.write

ghl_association_listA

Renamed from the auto-generated 'ghl_association_find' for consistency with other domain list-operation names. Get all associations for a sub-account / location Get all Associations Endpoint: GET /associations/ (Version header: v3; source: v3/associations-v3.json) OAuth scopes: associations.readonly Pagination params: skip, limit — pass them to page through full result sets.

ghl_association_get_by_key_nameC

Renamed from the auto-generated 'ghl_association_get_key_by_key_name' (redundant 'key_by_key_name'). Get association key by key name Using this api you can get standard / user defined association by key Endpoint: GET /associations/key/{key_name} (Version header: v3; source: v3/associations-v3.json) OAuth scopes: associations.readonly

ghl_association_get_by_object_keyC

Renamed from the auto-generated 'ghl_association_get_by_object_keys' — singular to match the single objectKey path param (plural 'keys' was misleading, it's one key per call). Get association by object keys Get association by object keys like contacts, custom objects and opportunities. Documentation Link - https://doc.clickup.com/8631005/d/h/87cpx-293776/cd0f4122abc04d3 Endpoint: GET /associations/objectKey/{objectKey} (Version header: v3; source: v3/associations-v3.json) OAuth scopes: associations.readonly

ghl_association_createB

Create Association Allow you to create contact - contact , contact - custom objects and business - contact associations, will add more in the future.Documentation Link - https://doc.clickup.com/8631005/d/h/87cpx-293776/cd0f4122abc04d3 Endpoint: POST /associations/ (Version header: v3; source: v3/associations-v3.json) OAuth scopes: associations.write

ghl_association_get_relations_by_record_idB

Get all relations By record Id Get all relations by record Id Endpoint: GET /associations/relations/{recordId} (Version header: v3; source: v3/associations-v3.json) OAuth scopes: associations/relation.readonly Pagination params: skip, limit — pass them to page through full result sets.

ghl_association_delete_relationC

Delete Relation Endpoint: DELETE /associations/relations/{relationId} (Version header: v3; source: v3/associations-v3.json) OAuth scopes: associations/relation.write

ghl_association_create_relationC

Create Relation for you associated entities. Create Relation.Documentation Link - https://doc.clickup.com/8631005/d/h/87cpx-293776/cd0f4122abc04d3 Endpoint: POST /associations/relations (Version header: v3; source: v3/associations-v3.json) OAuth scopes: associations/relation.write

ghl_blog_get_all_authors_by_locationA

Get all blog authors The "Get all blog authors" API returns the blog authors for a given location ID. Endpoint: GET /blogs/authors (Version header: v3; source: v3/blogs-v3.json) Requires a Sub-Account (location) token. OAuth scopes: blogs/author.readonly Pagination params: limit, offset — pass them to page through full result sets.

ghl_blog_get_all_categories_by_locationA

Get all blog categories The "Get all blog categories" API returns the blog categories for a given location ID. Endpoint: GET /blogs/categories (Version header: v3; source: v3/blogs-v3.json) Requires a Sub-Account (location) token. OAuth scopes: blogs/category.readonly Pagination params: limit, offset — pass them to page through full result sets.

ghl_blog_update_postA

Update Blog Post The "Update Blog Post" API updates an existing blog post for any given blog site. Endpoint: PUT /blogs/posts/{postId} (Version header: v3; source: v3/blogs-v3.json) Requires a Sub-Account (location) token. OAuth scopes: blogs/post-update.write

ghl_blog_post_listA

Lists all posts for a given blogId (operationId get-blog-post) — not a single-post fetch. Requires blogId + limit; paginated. Get Blog posts by Blog ID The "Get Blog posts by Blog ID" API returns the blog posts for a given blog site. Use searchTerm to search across post title, description, url slug and category name. Endpoint: GET /blogs/posts/all (Version header: v3; source: v3/blogs-v3.json) Requires a Sub-Account (location) token. OAuth scopes: blogs/posts.readonly Pagination params: limit, offset — pass them to page through full result sets.

ghl_blog_get_post_by_idA

Get Blog Post by ID The "Get Blog Post by ID" API returns a single published blog post, including its content/body, for the given location. Endpoint: GET /blogs/posts/post/{postId} (Version header: v3; source: v3/blogs-v3.json) Requires a Sub-Account (location) token. OAuth scopes: blogs/posts.readonly

ghl_blog_check_url_slug_existsA

Check url slug The "Check url slug" API checks whether a blog post url slug is already in use for the location. Call it before publishing a blog post. Endpoint: GET /blogs/posts/url-slug-exists (Version header: v3; source: v3/blogs-v3.json) Requires a Sub-Account (location) token. OAuth scopes: blogs/check-slug.readonly

ghl_blog_post_createA

Create Blog Post The "Create Blog Post" API allows you to create a blog post for any given blog site. Endpoint: POST /blogs/posts (Version header: v3; source: v3/blogs-v3.json) Requires a Sub-Account (location) token. OAuth scopes: blogs/post.write

ghl_blog_site_listA

Get Blogs by Location ID The "Get Blogs by Location ID" API allows you get blogs using Location ID. Endpoint: GET /blogs/site/all (Version header: v3; source: v3/blogs-v3.json) Requires a Sub-Account (location) token. OAuth scopes: blogs/list.readonly Pagination params: skip, limit — pass them to page through full result sets.

ghl_brand_board_set_default_voiceA

Set Default Brand Voice Set a brand voice as the default for a location. The previous default will be unset. Endpoint: POST /brand-boards/locations/{locationId}/brand-voices/{brandVoiceId}/default (Version header: v3; source: v3/brand-boards-v3.json) Requires a Sub-Account (location) token. OAuth scopes: brand-boards/voices.write

ghl_brand_board_delete_voiceA

Delete Brand Voice Delete a brand voice by ID Endpoint: DELETE /brand-boards/locations/{locationId}/brand-voices/{brandVoiceId} (Version header: v3; source: v3/brand-boards-v3.json) Requires a Sub-Account (location) token. OAuth scopes: brand-boards/voices.write

ghl_brand_board_get_voiceA

Get Brand Voice Get a brand voice by ID Endpoint: GET /brand-boards/locations/{locationId}/brand-voices/{brandVoiceId} (Version header: v3; source: v3/brand-boards-v3.json) Requires a Sub-Account (location) token. OAuth scopes: brand-boards/voices.readonly

ghl_brand_board_update_voiceA

Update Brand Voice Update a brand voice by ID Endpoint: PATCH /brand-boards/locations/{locationId}/brand-voices/{brandVoiceId} (Version header: v3; source: v3/brand-boards-v3.json) Requires a Sub-Account (location) token. OAuth scopes: brand-boards/voices.write

ghl_brand_board_list_voicesA

List Brand Voices Get list of brand voices for a location Endpoint: GET /brand-boards/locations/{locationId}/brand-voices (Version header: v3; source: v3/brand-boards-v3.json) Requires a Sub-Account (location) token. OAuth scopes: brand-boards/voices.readonly Pagination params: limit, offset — pass them to page through full result sets.

ghl_brand_board_create_voiceA

Create Brand Voice Create a brand voice for a location Endpoint: POST /brand-boards/locations/{locationId}/brand-voices (Version header: v3; source: v3/brand-boards-v3.json) Requires a Sub-Account (location) token. OAuth scopes: brand-boards/voices.write

ghl_brand_board_set_default_design_kitA

Set Default Design Kit Set a design kit as the default for a location. The previous default will be unset. Endpoint: POST /brand-boards/locations/{locationId}/design-kits/{designKitId}/default (Version header: v3; source: v3/brand-boards-v3.json) Requires a Sub-Account (location) token. OAuth scopes: brand-boards/design-kit.write

ghl_brand_board_delete_design_kitA

Delete Design Kit Delete a design kit by ID Endpoint: DELETE /brand-boards/locations/{locationId}/design-kits/{designKitId} (Version header: v3; source: v3/brand-boards-v3.json) Requires a Sub-Account (location) token. OAuth scopes: brand-boards/design-kit.write

ghl_brand_board_get_design_kitA

Get Design Kit Get a design kit by ID Endpoint: GET /brand-boards/locations/{locationId}/design-kits/{designKitId} (Version header: v3; source: v3/brand-boards-v3.json) Requires a Sub-Account (location) token. OAuth scopes: brand-boards/design-kit.readonly

ghl_brand_board_update_design_kitB

Update Design Kit Update a design kit by ID Endpoint: PATCH /brand-boards/locations/{locationId}/design-kits/{designKitId} (Version header: v3; source: v3/brand-boards-v3.json) Requires a Sub-Account (location) token. OAuth scopes: brand-boards/design-kit.write

ghl_brand_board_list_design_kitsA

List Design Kits Get list of design kits for a location Endpoint: GET /brand-boards/locations/{locationId}/design-kits (Version header: v3; source: v3/brand-boards-v3.json) Requires a Sub-Account (location) token. OAuth scopes: brand-boards/design-kit.readonly Pagination params: limit, offset — pass them to page through full result sets.

ghl_brand_board_create_design_kitA

Create Design Kit Create a design kit for a location Endpoint: POST /brand-boards/locations/{locationId}/design-kits (Version header: v3; source: v3/brand-boards-v3.json) Requires a Sub-Account (location) token. OAuth scopes: brand-boards/design-kit.write

ghl_business_deleteB

Delete Business Endpoint: DELETE /businesses/{businessId} (Version header: v3; source: v3/businesses-v3.json) OAuth scopes: businesses.write

ghl_business_getA

Get Business Endpoint: GET /businesses/{businessId} (Version header: v3; source: v3/businesses-v3.json) OAuth scopes: businesses.readonly

ghl_business_updateC

Update Business Endpoint: PUT /businesses/{businessId} (Version header: v3; source: v3/businesses-v3.json) OAuth scopes: businesses.write

ghl_business_get_businesses_by_locationB

Get Businesses by Location Endpoint: GET /businesses/ (Version header: v3; source: v3/businesses-v3.json) OAuth scopes: businesses.readonly Pagination params: limit, skip — pass them to page through full result sets.

ghl_business_createA

Create Business Endpoint: POST /businesses/ (Version header: v3; source: v3/businesses-v3.json) OAuth scopes: businesses.write

ghl_calendar_list_free_slotsA

startDate/endDate are epoch milliseconds (a number, e.g. 1548898600000), NOT an ISO date string, despite the parameter name. Date range cannot exceed 31 days. Get Free Slots Get free slots for a calendar between a date range. Optionally a consumer can also request free slots in a particular timezone and also for a particular user. Endpoint: GET /calendars/{calendarId}/free-slots (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars.readonly

ghl_calendar_notification_deleteA

Delete Notification Delete notification Endpoint: DELETE /calendars/{calendarId}/notifications/{notificationId} (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars/events.write

ghl_calendar_notification_getA

Get notification Find Event notification by notificationId Endpoint: GET /calendars/{calendarId}/notifications/{notificationId} (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars/events.readonly

ghl_calendar_notification_updateB

Update notification Update Event notification by id Endpoint: PUT /calendars/{calendarId}/notifications/{notificationId} (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars/events.write

ghl_calendar_notification_listA

Get notifications Get calendar notifications based on query Endpoint: GET /calendars/{calendarId}/notifications (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars/events.readonly Pagination params: limit, skip — pass them to page through full result sets.

ghl_calendar_notification_createA

Create notification Create Calendar notifications, either one or multiple. All notification settings must be for single calendar only Endpoint: POST /calendars/{calendarId}/notifications (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars/events.write

ghl_calendar_deleteA

Delete Calendar Delete calendar by ID Endpoint: DELETE /calendars/{calendarId} (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars.write

ghl_calendar_getA

Get Calendar Get calendar by ID Endpoint: GET /calendars/{calendarId} (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars.readonly

ghl_calendar_updateB

Update Calendar Update calendar by ID. Endpoint: PUT /calendars/{calendarId} (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars.write

ghl_calendar_appointment_note_deleteB

Delete Note Endpoint: DELETE /calendars/appointments/{appointmentId}/notes/{noteId} (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars/events.write

ghl_calendar_appointment_note_updateB

Update Note Endpoint: PUT /calendars/appointments/{appointmentId}/notes/{noteId} (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars/events.write

ghl_calendar_appointment_note_listA

Get Notes Get Appointment Notes Endpoint: GET /calendars/appointments/{appointmentId}/notes (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars/events.readonly Pagination params: limit, offset — pass them to page through full result sets.

ghl_calendar_appointment_note_createC

Create Note Endpoint: POST /calendars/appointments/{appointmentId}/notes (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars/events.write

ghl_calendar_list_blocked_slotsB

startTime/endTime are epoch milliseconds passed as strings. Get Blocked Slots Endpoint: GET /calendars/blocked-slots (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars/events.readonly

ghl_calendar_event_deleteA

Deletes any calendar event by ID (appointment or block-slot). Use ghl_calendar_appointment_* or ghl_calendar_block_slot_* for type-specific create/get/update. Delete Event Delete event by ID Endpoint: DELETE /calendars/events/{eventId} (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars/events.write

ghl_calendar_appointment_getB

Get Appointment Get appointment by ID Endpoint: GET /calendars/events/appointments/{eventId} (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars/events.readonly

ghl_calendar_appointment_updateC

Update Appointment Update appointment Endpoint: PUT /calendars/events/appointments/{eventId} (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars/events.write

ghl_calendar_appointment_createB

Create appointment Endpoint: POST /calendars/events/appointments (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars/events.write

ghl_calendar_block_slot_updateB

Update Block Slot Update block slot by ID Endpoint: PUT /calendars/events/block-slots/{eventId} (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars/events.write

ghl_calendar_block_slot_createC

Create Block Slot Create block slot Endpoint: POST /calendars/events/block-slots (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars/events.write

ghl_calendar_event_listC

Get Calendar Events Endpoint: GET /calendars/events (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars/events.readonly

ghl_calendar_listB

Get Calendars Get all calendars in a location. Endpoint: GET /calendars/ (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars.readonly

ghl_calendar_group_update_statusA

Despite the underlying 'disable-group' operation name, the required body field isActive (boolean) toggles both directions — set isActive:true to re-enable the group. Disable Group Endpoint: PUT /calendars/groups/{groupId}/status (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars/groups.write

ghl_calendar_group_deleteC

Delete Group Endpoint: DELETE /calendars/groups/{groupId} (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars/groups.write

ghl_calendar_group_updateB

Update Group Update Group by group ID Endpoint: PUT /calendars/groups/{groupId} (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars/groups.write

ghl_calendar_group_validate_slugB

Validate group slug Validate if group slug is available or not. Endpoint: POST /calendars/groups/validate-slug (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars/groups.write

ghl_calendar_group_listA

Get Groups Get all calendar groups in a location. Endpoint: GET /calendars/groups (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars/groups.readonly

ghl_calendar_group_createA

Create Calendar Group Endpoint: POST /calendars/groups (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars/groups.write

ghl_calendar_createB

Create Calendar Create calendar in a location. Endpoint: POST /calendars/ (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars.write

ghl_calendar_resource_deleteB

Uses the currently-documented (non-deprecated) Calendar Resources version, 2021-04-15. The v3-tagged variant of this operation in the v3 spec is marked deprecated (Services V1) with identical request/response fields — do not use Version: v3 for resource endpoints. Delete Calendar Resource Delete calendar resource by ID (Services V1) Endpoint: DELETE /calendars/resources/{resourceType}/{id} (Version header: v3; source: v3/calendars-v3.json) Requires a Sub-Account (location) token. OAuth scopes: calendars/resources.write

ghl_calendar_resource_getA

Uses the currently-documented (non-deprecated) Calendar Resources version, 2021-04-15. The v3-tagged variant of this operation in the v3 spec is marked deprecated (Services V1) with identical request/response fields — do not use Version: v3 for resource endpoints. Get Calendar Resource Get calendar resource by ID (Services V1) Endpoint: GET /calendars/resources/{resourceType}/{id} (Version header: v3; source: v3/calendars-v3.json) Requires a Sub-Account (location) token. OAuth scopes: calendars/resources.readonly

ghl_calendar_resource_updateA

Uses the currently-documented (non-deprecated) Calendar Resources version, 2021-04-15. The v3-tagged variant of this operation in the v3 spec is marked deprecated (Services V1) with identical request/response fields — do not use Version: v3 for resource endpoints. Update Calendar Resource Update calendar resource by ID (Services V1) Endpoint: PUT /calendars/resources/{resourceType}/{id} (Version header: v3; source: v3/calendars-v3.json) Requires a Sub-Account (location) token. OAuth scopes: calendars/resources.write

ghl_calendar_resource_listA

Uses the currently-documented (non-deprecated) Calendar Resources version, 2021-04-15. The v3-tagged variant of this operation in the v3 spec is marked deprecated (Services V1) with identical request/response fields — do not use Version: v3 for resource endpoints. List Calendar Resources List calendar resources by resource type and location ID (Services V1) Endpoint: GET /calendars/resources/{resourceType} (Version header: v3; source: v3/calendars-v3.json) Requires a Sub-Account (location) token. OAuth scopes: calendars/resources.readonly Pagination params: limit, skip — pass them to page through full result sets.

ghl_calendar_resource_createB

Uses the currently-documented (non-deprecated) Calendar Resources version, 2021-04-15. The v3-tagged variant of this operation in the v3 spec is marked deprecated (Services V1) with identical request/response fields — do not use Version: v3 for resource endpoints. Create Calendar Resource Create calendar resource by resource type (Services V1) Endpoint: POST /calendars/resources/{resourceType} (Version header: v3; source: v3/calendars-v3.json) Requires a Sub-Account (location) token. OAuth scopes: calendars/resources.write

ghl_calendar_schedule_unassignA

Removes a user availability schedule association from the given calendar. Remove user availability schedule from a calendar Removes the association between a team calendar and the given schedule by removing the calendarId from the schedule Endpoint: DELETE /calendars/schedules/{id}/associations/{calendarId} (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars.write

ghl_calendar_schedule_assignB

Applies an existing user availability schedule to the given calendar. Apply user availability schedule to a calendar Associates a calendar with the given schedule by adding the calendarId to a schedule Endpoint: PUT /calendars/schedules/{id}/associations/{calendarId} (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars.write

ghl_calendar_schedule_deleteA

Delete user availability schedule Permanently remove a schedule and all its associated rules. This action cannot be undone. Endpoint: DELETE /calendars/schedules/{id} (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars.write

ghl_calendar_schedule_getA

Get user availability schedule Retrieve a specific schedule by its unique identifier. Returns detailed information including rules, timezone, and associated calendars/users. Endpoint: GET /calendars/schedules/{id} (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars.readonly

ghl_calendar_schedule_updateA

Update user availability schedule Modify an existing schedule by updating its rules, timezone, and name All fields are optional - only provided fields will be updated. Endpoint: PUT /calendars/schedules/{id} (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars.write

ghl_calendar_event_schedule_getB

Get event calendar availability schedule Retrieve the availability schedule for a specific event calendar. Returns the schedule associated with the calendar ID provided in the path. Endpoint: GET /calendars/schedules/event-calendar/{calendarId} (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars.readonly

ghl_calendar_event_schedule_createA

Create event calendar availability schedule Create a new availability schedule specifically for an event calendar. The calendar ID is provided in the path, and schedule rules and timezone are provided in the request body. Endpoint: POST /calendars/schedules/event-calendar/{calendarId} (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars.write

ghl_calendar_event_schedule_updateA

Update event calendar availability schedule Update the availability schedule for a specific event calendar. Only provided fields will be updated. The calendar ID is provided in the path. Endpoint: PUT /calendars/schedules/event-calendar/{calendarId} (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars.write

ghl_calendar_schedule_listA

List user availability schedule Retrieve user availability schedules based on various filters including location, calendar, and user. Supports pagination. Endpoint: GET /calendars/schedules/search (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars.readonly Pagination params: skip, limit — pass them to page through full result sets.

ghl_calendar_schedule_createA

Create user availability schedule Create new schedule with specified rules, timezone, location, user and calendar associations. Endpoint: POST /calendars/schedules (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars.write

ghl_calendar_service_booking_deleteA

Delete Service Booking Delete a service booking by ID Endpoint: DELETE /calendars/services/bookings/{bookingId} (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars/events.write

ghl_calendar_service_booking_getB

Get Service Booking by ID Get a specific service booking by ID Endpoint: GET /calendars/services/bookings/{bookingId} (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars/events.readonly

ghl_calendar_service_booking_updateB

Update Service Booking Update an existing service booking Endpoint: PUT /calendars/services/bookings/{bookingId} (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars/events.write

ghl_calendar_service_booking_listA

startTime/endTime are epoch milliseconds passed as strings. No limit/offset — results are bounded by the required date range. Get Service Bookings Retrieve service bookings for a location within a given date range, with an optional service location filter. Endpoint: GET /calendars/services/bookings (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars/events.readonly

ghl_calendar_service_booking_createB

Create Service Booking Create a new service booking Endpoint: POST /calendars/services/bookings (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars/events.write

ghl_calendar_service_deleteB

Delete Service Delete service by ID. Endpoint: DELETE /calendars/services/catalog/{serviceId} (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars.write

ghl_calendar_service_getA

Get Service by ID Get service by ID. Endpoint: GET /calendars/services/catalog/{serviceId} (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars.readonly

ghl_calendar_service_updateB

Update Service Update service by ID. Endpoint: PUT /calendars/services/catalog/{serviceId} (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars.write

ghl_calendar_service_listB

Get Services Get all services in a location. Endpoint: GET /calendars/services/catalog (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars.readonly

ghl_calendar_service_createA

Create Service Create new service in a location. Endpoint: POST /calendars/services/catalog (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars.write

ghl_calendar_service_location_deleteA

Delete Service Location Delete a service location by ID Endpoint: DELETE /calendars/services/locations/{serviceLocationId} (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars.write

ghl_calendar_service_location_getB

Get Service Location by ID Get service location by ID Endpoint: GET /calendars/services/locations/{serviceLocationId} (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars.readonly

ghl_calendar_service_location_updateA

Update Service Location Update an existing service location Endpoint: PUT /calendars/services/locations/{serviceLocationId} (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars.write

ghl_calendar_service_location_listC

Get Service Locations Get all service locations Endpoint: GET /calendars/services/locations (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars.readonly

ghl_calendar_service_location_createB

Create Service Location Create a new service location Endpoint: POST /calendars/services/locations (Version header: v3; source: v3/calendars-v3.json) OAuth scopes: calendars.write

ghl_campaign_listC

Get Campaigns Endpoint: GET /campaigns/ (Version header: v3; source: v3/campaigns-v3.json) OAuth scopes: campaigns.readonly

ghl_chat_widget_deleteA

Delete a Chat Widget Deletes a chat widget by ID Endpoint: DELETE /chat-widget/{locationId}/{id} (Version header: v3; source: v3/chat-widget-v3.json) Requires a Sub-Account (location) token. OAuth scopes: chat-widget.write

ghl_chat_widget_cloneA

Clone a Chat Widget Clones an existing chat widget into a new widget Endpoint: POST /chat-widget/clone (Version header: v3; source: v3/chat-widget-v3.json) Requires a Sub-Account (location) token. OAuth scopes: chat-widget.write

ghl_chat_widget_getA

Get Chat Widget by ID Returns the full chat widget configuration for the given location and widget ID Endpoint: GET /chat-widget/data/{locationId}/{id} (Version header: v3; source: v3/chat-widget-v3.json) Requires a Sub-Account (location) token. OAuth scopes: chat-widget.readonly

ghl_chat_widget_patchA

Patch Chat Widget Applies a partial update to an existing chat widget Endpoint: PATCH /chat-widget/data/{locationId}/{id} (Version header: v3; source: v3/chat-widget-v3.json) Requires a Sub-Account (location) token. OAuth scopes: chat-widget.write

ghl_chat_widget_updateA

Update Chat Widget Replaces an existing chat widget with the provided configuration Endpoint: PUT /chat-widget/data/{locationId}/{id} (Version header: v3; source: v3/chat-widget-v3.json) Requires a Sub-Account (location) token. OAuth scopes: chat-widget.write

ghl_chat_widget_listA

List Chat Widgets Retrieves a list of chat widgets for a specific location Endpoint: GET /chat-widget/list (Version header: v3; source: v3/chat-widget-v3.json) Requires a Sub-Account (location) token. OAuth scopes: chat-widget.readonly Pagination params: offset, limit — pass them to page through full result sets.

ghl_chat_widget_createA

Create a new chat widget Creates a new chat widget for a specific location Endpoint: POST /chat-widget/ (Version header: v3; source: v3/chat-widget-v3.json) Requires a Sub-Account (location) token. OAuth scopes: chat-widget.write

ghl_clientportal_list_templatesB

CLIENT PORTAL AI BUILDER API (/ai-builder-api) — side-effecting: opens/edits sandboxes and starts builds. Edit a sandbox only once sandbox.status is ready; checkpoint after edits and before starting the run that builds them; 409 means a cloud build owns the sandbox or it is not running. List the app templates a project can be created from. The template catalog powers the template picker on the landing page: the starters, then the vertical templates (ready-made vibe apps that the Jenkins vertical-templates-release publishes). Each entry has a stable id, a category, a human-readable name + summary, a version, and the stackTemplate a project from it is created on. A vertical template also names the CP Elements products it uses, and its card picture when it has one (previewUrl). Pass the chosen id as templateId and its stackTemplate on createProject. Endpoint: GET /ai-builder-api/catalog/templates (Version header: v3; source: v3/clientportal-ai-v3.json) OAuth scopes: clientportal-ai.readonly

ghl_clientportal_cli_get_project_contextA

CLIENT PORTAL AI BUILDER API (/ai-builder-api) — side-effecting: opens/edits sandboxes and starts builds. Edit a sandbox only once sandbox.status is ready; checkpoint after edits and before starting the run that builds them; 409 means a cloud build owns the sandbox or it is not running. Read an app's stack and open its sandbox for editing. Returns the app's stack, which decides how its code is written, and its kernel bundle, and opens the app's sandbox: read and edit it once sandbox.status is ready. A react_native_app_kernel_v1 app is a phone app: its screens are files under apps/mobile/app-extensions/, registered with POST .../sandbox/extension-routes. Every other stack is a web portal. Endpoint: GET /ai-builder-api/cli/projects/{projectId}/context (Version header: v3; source: v3/clientportal-ai-v3.json) OAuth scopes: clientportal-ai.write

ghl_clientportal_cli_sandbox_checkpointA

CLIENT PORTAL AI BUILDER API (/ai-builder-api) — side-effecting: opens/edits sandboxes and starts builds. Edit a sandbox only once sandbox.status is ready; checkpoint after edits and before starting the run that builds them; 409 means a cloud build owns the sandbox or it is not running. Save the app's sandbox files as the point it restarts from. Saves the sandbox's files so a sandbox that restarts comes back with them. Call it after a set of POST .../sandbox/edit calls and before starting the run that builds them: a sandbox that restarts in between otherwise comes back with the files as they were at the last save. Endpoint: POST /ai-builder-api/cli/projects/{projectId}/sandbox/checkpoint (Version header: v3; source: v3/clientportal-ai-v3.json) OAuth scopes: clientportal-ai.write

ghl_clientportal_cli_sandbox_editA

CLIENT PORTAL AI BUILDER API (/ai-builder-api) — side-effecting: opens/edits sandboxes and starts builds. Edit a sandbox only once sandbox.status is ready; checkpoint after edits and before starting the run that builds them; 409 means a cloud build owns the sandbox or it is not running. Write or delete one file in the app's sandbox. Writes or deletes one file in the app's sandbox. After a set of edits, save them with POST .../sandbox/checkpoint, then start a run with externalAgent: true to check, build and deploy them. A React Native app (react_native_app_kernel_v1) writes only under apps/mobile/app-extensions/ and apps/mobile/application-assets/; its routes.ts is generated, so register its screens with POST .../sandbox/extension-routes instead of writing that file. Endpoint: POST /ai-builder-api/cli/projects/{projectId}/sandbox/edit (Version header: v3; source: v3/clientportal-ai-v3.json) OAuth scopes: clientportal-ai.write

ghl_clientportal_cli_sandbox_register_extension_routeA

CLIENT PORTAL AI BUILDER API (/ai-builder-api) — side-effecting: opens/edits sandboxes and starts builds. Edit a sandbox only once sandbox.status is ready; checkpoint after edits and before starting the run that builds them; 409 means a cloud build owns the sandbox or it is not running. Register, rename or remove a React Native app's screens. Changes the screen list of a React Native app (react_native_app_kernel_v1) once its screen files are written with POST .../sandbox/edit: app-extensions/routes.ts is generated from these changes, never written as text. Send several changes as one batch: all of them apply or none does, and a resent batch that is already in effect changes nothing (a repeated single add is refused as duplicate_id). The run started next with externalAgent: true checks the screens, saves them as a mobile revision and deploys the preview. Endpoint: POST /ai-builder-api/cli/projects/{projectId}/sandbox/extension-routes (Version header: v3; source: v3/clientportal-ai-v3.json) OAuth scopes: clientportal-ai.write

ghl_clientportal_cli_sandbox_searchA

CLIENT PORTAL AI BUILDER API (/ai-builder-api) — side-effecting: opens/edits sandboxes and starts builds. Edit a sandbox only once sandbox.status is ready; checkpoint after edits and before starting the run that builds them; 409 means a cloud build owns the sandbox or it is not running. Search the app's code for literal text. Finds where text appears in the app's source files (ts, tsx, js, jsx, vue, json, md, css), with dependencies and build output left out. The text is matched literally, not as a pattern. Read the files it finds with POST .../sandbox/view. Endpoint: POST /ai-builder-api/cli/projects/{projectId}/sandbox/search (Version header: v3; source: v3/clientportal-ai-v3.json) OAuth scopes: clientportal-ai.readonly

ghl_clientportal_cli_sandbox_viewA

CLIENT PORTAL AI BUILDER API (/ai-builder-api) — side-effecting: opens/edits sandboxes and starts builds. Edit a sandbox only once sandbox.status is ready; checkpoint after edits and before starting the run that builds them; 409 means a cloud build owns the sandbox or it is not running. Read a file in the app's sandbox, or list a folder. Reads one file of the app's code, or lists a folder's files and subfolders, so an agent sees what is there before it edits. A folder path always lists. The kernel's own files are readable; the writable boundary applies only to POST .../sandbox/edit. Endpoint: POST /ai-builder-api/cli/projects/{projectId}/sandbox/view (Version header: v3; source: v3/clientportal-ai-v3.json) OAuth scopes: clientportal-ai.readonly

ghl_clientportal_get_mobile_apk_buildB

CLIENT PORTAL AI BUILDER API (/ai-builder-api) — side-effecting: opens/edits sandboxes and starts builds. Edit a sandbox only once sandbox.status is ready; checkpoint after edits and before starting the run that builds them; 409 means a cloud build owns the sandbox or it is not running. Get an APK build's status and download link. Read it again until status is finished, when artifactUrl is a short-lived download link, or failed, when error says why. Endpoint: GET /ai-builder-api/projects/{projectId}/app-config/apk-builds/{apkBuildId} (Version header: v3; source: v3/clientportal-ai-v3.json) OAuth scopes: clientportal-ai.readonly

ghl_clientportal_request_mobile_apk_buildA

CLIENT PORTAL AI BUILDER API (/ai-builder-api) — side-effecting: opens/edits sandboxes and starts builds. Edit a sandbox only once sandbox.status is ready; checkpoint after edits and before starting the run that builds them; 409 means a cloud build owns the sandbox or it is not running. Build a signed Android APK of a published phone app revision. Idempotent per Idempotency-Key. For a project whose current revision carries generated screens, the build is instead identified by the revision and the generated sources it carries (sha256(locationId:projectId:revision:sourcesSha)): repeating the request for the same revision and sources returns the same build whatever the key, and a failed one is queued again. Such a build is made from the React Native kernel commit the screens were generated against, and must be requested for the current revision. Generated screens reach members only through a new APK; they are never delivered over the air. At most one build may be active per project; sibling projects in the same location may build in parallel. Deleting a project while its build is still queued or building fails that build. A project compiles one signed APK for now: after a successful build the binary is final. A project without generated screens keeps reaching installed apps by publishing a revision; a project with generated screens cannot build another APK yet. Failed builds do not consume the allowance. Endpoint: POST /ai-builder-api/projects/{projectId}/app-config/apk-builds (Version header: v3; source: v3/clientportal-ai-v3.json) OAuth scopes: clientportal-ai.write

ghl_clientportal_create_mobile_experience_preview_tokenB

CLIENT PORTAL AI BUILDER API (/ai-builder-api) — side-effecting: opens/edits sandboxes and starts builds. Edit a sandbox only once sandbox.status is ready; checkpoint after edits and before starting the run that builds them; 409 means a cloud build owns the sandbox or it is not running. Create a preview link token for a phone app. A short-lived token that makes the app's preview show this app. Open sandbox.devUrl from GET .../cli/projects/{projectId}/context with #previewToken=<token> appended; without it the preview shows the stock app. Endpoint: POST /ai-builder-api/projects/{projectId}/app-config/mobile-preview-token (Version header: v3; source: v3/clientportal-ai-v3.json) OAuth scopes: clientportal-ai.readonly

ghl_clientportal_publish_app_customizationA

CLIENT PORTAL AI BUILDER API (/ai-builder-api) — side-effecting: opens/edits sandboxes and starts builds. Edit a sandbox only once sandbox.status is ready; checkpoint after edits and before starting the run that builds them; 409 means a cloud build owns the sandbox or it is not running. Publish a saved revision of an app to its members. For a phone app send platform: mobile and the revision from GET .../app-config: installed apps get it over the air. Screens your agent wrote reach members only in a new APK (POST .../app-config/apk-builds). web, the default, is for ClientPortal configuration apps; a coded web app publishes with POST .../infra/promote-to-production. Endpoint: POST /ai-builder-api/projects/{projectId}/app-config/publish (Version header: v3; source: v3/clientportal-ai-v3.json) OAuth scopes: clientportal-ai.write

ghl_clientportal_restore_mobile_customization_revisionA

CLIENT PORTAL AI BUILDER API (/ai-builder-api) — side-effecting: opens/edits sandboxes and starts builds. Edit a sandbox only once sandbox.status is ready; checkpoint after edits and before starting the run that builds them; 409 means a cloud build owns the sandbox or it is not running. Return a phone app to an earlier revision. Saves a copy of the earlier revision, screens included, as the newest one. Members get it once you publish it with POST .../app-config/publish. Endpoint: POST /ai-builder-api/projects/{projectId}/app-config/revisions/{revision}/restore (Version header: v3; source: v3/clientportal-ai-v3.json) OAuth scopes: clientportal-ai.write

ghl_clientportal_list_mobile_customization_revisionsC

CLIENT PORTAL AI BUILDER API (/ai-builder-api) — side-effecting: opens/edits sandboxes and starts builds. Edit a sandbox only once sandbox.status is ready; checkpoint after edits and before starting the run that builds them; 409 means a cloud build owns the sandbox or it is not running. List a phone app's saved revisions. Up to 50, newest first, marking the current one and the one members get. Return to one with POST .../app-config/revisions/{revision}/restore. Endpoint: GET /ai-builder-api/projects/{projectId}/app-config/revisions (Version header: v3; source: v3/clientportal-ai-v3.json) OAuth scopes: clientportal-ai.readonly

ghl_clientportal_get_app_customizationB

CLIENT PORTAL AI BUILDER API (/ai-builder-api) — side-effecting: opens/edits sandboxes and starts builds. Edit a sandbox only once sandbox.status is ready; checkpoint after edits and before starting the run that builds them; 409 means a cloud build owns the sandbox or it is not running. Get which revision of an app is newest, applied and published. A phone app saves a revision at the end of each run. Publish it with POST .../app-config/publish once appliedRevision equals revision and status is ready. Endpoint: GET /ai-builder-api/projects/{projectId}/app-config (Version header: v3; source: v3/clientportal-ai-v3.json) OAuth scopes: clientportal-ai.readonly

ghl_clientportal_apply_project_changeA

CLIENT PORTAL AI BUILDER API (/ai-builder-api) — side-effecting: opens/edits sandboxes and starts builds. Edit a sandbox only once sandbox.status is ready; checkpoint after edits and before starting the run that builds them; 409 means a cloud build owns the sandbox or it is not running. Apply a signed plan once. Idempotent on planId: a second (or concurrent) apply of the same plan returns the first apply's result without writing again (queued while the first is still running). Apply re-checks the stored change against what exists now; when it moved, the answer is 409 change_plan_stale with a fix (plan again). An expired plan is 409 too. A partial result stays open: applying the same plan again finishes only what is left. Another location's or project's plan is 404. Endpoint: POST /ai-builder-api/projects/{projectId}/changes/apply (Version header: v3; source: v3/clientportal-ai-v3.json) OAuth scopes: clientportal-ai.write

ghl_clientportal_plan_project_changeA

CLIENT PORTAL AI BUILDER API (/ai-builder-api) — side-effecting: opens/edits sandboxes and starts builds. Edit a sandbox only once sandbox.status is ready; checkpoint after edits and before starting the run that builds them; 409 means a cloud build owns the sandbox or it is not running. Check a change of one kind and sign a plan for it, without writing anything. The caller's AI writes a change of one kind; the server validates it against that kind's schema and against what exists now (CRM, modules, saved customization) and answers what applying it would do. Nothing is written and no model is called. planId is a signed token over {projectId, locationId, kind, changeHash} that expires at expiresAt; it is null when ok is false. The location is the session's, never the body's. Kinds: records, modules, appearance, mobile, assets, domain; any other kind is 400 unsupported_change_kind naming the supported ones. assets plans also return upload: PUT the image bytes to upload.url with upload.headers, then apply (apply is 409 customizer_image_not_uploaded until they land, and the plan stays open). domain apply returns the DNS records to add in result.dnsRecords; GET /custom-domains reports when it is active. Endpoint: POST /ai-builder-api/projects/{projectId}/changes/plan (Version header: v3; source: v3/clientportal-ai-v3.json) OAuth scopes: clientportal-ai.write

ghl_clientportal_get_project_change_schemaB

CLIENT PORTAL AI BUILDER API (/ai-builder-api) — side-effecting: opens/edits sandboxes and starts builds. Edit a sandbox only once sandbox.status is ready; checkpoint after edits and before starting the run that builds them; 409 means a cloud build owns the sandbox or it is not running. JSON Schema and an example for each change kind. Static per server release: what change must look like for each kind POST /changes/plan accepts, as JSON Schema (draft 2020-12, input shape) with one valid example. Endpoint: GET /ai-builder-api/projects/{projectId}/changes/schema (Version header: v3; source: v3/clientportal-ai-v3.json) OAuth scopes: clientportal-ai.readonly

ghl_clientportal_list_project_custom_domainsB

CLIENT PORTAL AI BUILDER API (/ai-builder-api) — side-effecting: opens/edits sandboxes and starts builds. Edit a sandbox only once sandbox.status is ready; checkpoint after edits and before starting the run that builds them; 409 means a cloud build owns the sandbox or it is not running. List the custom domains attached to a project. Lists the app's custom domains with their setup status and the DNS records to add. A domain is attached with changes kind domain; once it is active it serves the live site. Endpoint: GET /ai-builder-api/projects/{projectId}/custom-domains (Version header: v3; source: v3/clientportal-ai-v3.json) OAuth scopes: clientportal-ai.readonly

ghl_clientportal_promote_project_to_productionA

CLIENT PORTAL AI BUILDER API (/ai-builder-api) — side-effecting: opens/edits sandboxes and starts builds. Edit a sandbox only once sandbox.status is ready; checkpoint after edits and before starting the run that builds them; 409 means a cloud build owns the sandbox or it is not running. Publish an app to its live site. Publishes the app to its live site: its managed address, and every custom domain attached to it (changes kind domain) once that domain is active. A domain that becomes active later joins the live site without another publish. Check GET .../publishability first and send the sourceRunId it returns, so the build the creator approved is the one that goes live. Returns a publish job: poll GET .../infra/publish-jobs/{publishJobId} until status is succeeded (publishedUrl is the live site) or failed (error says why). Send the same idempotencyKey to retry safely. Endpoint: POST /ai-builder-api/projects/{projectId}/infra/promote-to-production (Version header: v3; source: v3/clientportal-ai-v3.json) OAuth scopes: clientportal-ai.write

ghl_clientportal_get_project_publish_jobB

CLIENT PORTAL AI BUILDER API (/ai-builder-api) — side-effecting: opens/edits sandboxes and starts builds. Edit a sandbox only once sandbox.status is ready; checkpoint after edits and before starting the run that builds them; 409 means a cloud build owns the sandbox or it is not running. Read a publish job's progress. Reports a publish job's progress. Poll it every few seconds until status is succeeded, when publishedUrl is the live site, or failed, when error says why. Endpoint: GET /ai-builder-api/projects/{projectId}/infra/publish-jobs/{publishJobId} (Version header: v3; source: v3/clientportal-ai-v3.json) OAuth scopes: clientportal-ai.readonly

ghl_clientportal_get_project_publishabilityA

CLIENT PORTAL AI BUILDER API (/ai-builder-api) — side-effecting: opens/edits sandboxes and starts builds. Edit a sandbox only once sandbox.status is ready; checkpoint after edits and before starting the run that builds them; 409 means a cloud build owns the sandbox or it is not running. Check whether an app can be published now, and which build would go live. Computed by the same resolver as promote-to-production. Without sourceRunId: publishable iff some ready run of this project (caller's location, main lineage) has a sealed build; the newest one goes live with the newest config-only revision made on its lineage. With sourceRunId (the reviewed preview): publishes what that preview shows — its own sealed build, or for a ready run that built nothing, the sealed build it descends from with config-only edits on that lineage; a run that failed or has not finished is reviewed_preview_not_publishable. Send the returned sourceRunId on promote-to-production. Tenant scope comes from the session only. Endpoint: GET /ai-builder-api/projects/{projectId}/publishability (Version header: v3; source: v3/clientportal-ai-v3.json) OAuth scopes: clientportal-ai.readonly

ghl_clientportal_answer_agent_run_questions_batchA

CLIENT PORTAL AI BUILDER API (/ai-builder-api) — side-effecting: opens/edits sandboxes and starts builds. Edit a sandbox only once sandbox.status is ready; checkpoint after edits and before starting the run that builds them; 409 means a cloud build owns the sandbox or it is not running. Answer every question of one form in a single write. Records up to 12 answers in one run write and resumes the run once, so a multi-question form does not resume the planner per answer. Same per-answer rules as POST …/answers (records review approval by approve:<reviewId> only, decline:<reviewId> declines, anything else is a change request); attachmentIds are ignored here. Project-scoped (404 for another project's run); locationId comes from the session, never from the body.

Idempotency: an answer whose capId and correlationId match the recorded one is skipped; when every answer is such a duplicate nothing is written and the run is not resumed again (still 202). Endpoint: POST /ai-builder-api/projects/{projectId}/runs/{runId}/answers/batch (Version header: v3; source: v3/clientportal-ai-v3.json) OAuth scopes: clientportal-ai.write

ghl_clientportal_get_agent_runB

CLIENT PORTAL AI BUILDER API (/ai-builder-api) — side-effecting: opens/edits sandboxes and starts builds. Edit a sandbox only once sandbox.status is ready; checkpoint after edits and before starting the run that builds them; 409 means a cloud build owns the sandbox or it is not running. Get the current state of a run (poll-friendly). Strictly tenant- and project-scoped. A run that exists under a different projectId (or under a different tenant entirely) returns 404 not_found — never 403, never the run record. This matches OWASP API1:2023 Broken Object Level Authorization guidance: same shape for "doesn't exist" and "not yours". Endpoint: GET /ai-builder-api/projects/{projectId}/runs/{runId} (Version header: v3; source: v3/clientportal-ai-v3.json) OAuth scopes: clientportal-ai.readonly

ghl_clientportal_list_agent_runs_for_projectA

CLIENT PORTAL AI BUILDER API (/ai-builder-api) — side-effecting: opens/edits sandboxes and starts builds. Edit a sandbox only once sandbox.status is ready; checkpoint after edits and before starting the run that builds them; 409 means a cloud build owns the sandbox or it is not running. List an app's runs, newest first. Returns the project's runs ordered newest-first by createdAt. The FE calls this when a user reopens a project to rebuild the chat history; pair with listAgentRunEvents per run to replay each prompt's full event log.

Production-backed by Mongo (ai_builder_runs_records). Persists across pod restarts and is shared across pods. Endpoint: GET /ai-builder-api/projects/{projectId}/runs (Version header: v3; source: v3/clientportal-ai-v3.json) OAuth scopes: clientportal-ai.readonly Pagination params: limit — pass them to page through full result sets.

ghl_clientportal_submit_agent_runA

CLIENT PORTAL AI BUILDER API (/ai-builder-api) — side-effecting: opens/edits sandboxes and starts builds. Edit a sandbox only once sandbox.status is ready; checkpoint after edits and before starting the run that builds them; 409 means a cloud build owns the sandbox or it is not running. Submit a prompt; the agent runs in the background. Returns runId immediately. A sub-account token builds with its own agent: it writes the code with POST .../sandbox/edit (and registers a React Native app's screens with POST .../sandbox/extension-routes), saves the files with POST .../sandbox/checkpoint, then starts the run with externalAgent: true, which checks, builds and deploys them. Poll GET .../runs/{runId}: problems a passing build still has are in checkProblems.

The builder's own agent executes asynchronously: attempt workspace restore from project's prior run → materialise scaffold (only if no prior workspace) → loop tool calls → preflight pnpm build → flush workspace to GCS → deploy via Cloud Build → managed runtime revision replace → mark ready with a preview URL.

Per-project runtime services receive a stable public app hostname so the iframe URL works without platform-session auth.

Idempotency: callers SHOULD send an Idempotency-Key header on every retry. The server stores (locationId, projectId, key) → runId for 24 h. Same key + same body → the original runId is replayed. Same key + different body → 409 idempotency_conflict. Modeled after standard idempotent POST contracts; safe for browser retries, network blips, and double-click submits.

Attachment scope: when attachmentIds are present, each id is verified against the caller's tenant + project. Cross-project or cross-tenant reuse is rejected with 403 attachment_not_owned. Endpoint: POST /ai-builder-api/projects/{projectId}/runs (Version header: v3; source: v3/clientportal-ai-v3.json) OAuth scopes: clientportal-ai.write

ghl_clientportal_get_projectC

CLIENT PORTAL AI BUILDER API (/ai-builder-api) — side-effecting: opens/edits sandboxes and starts builds. Edit a sandbox only once sandbox.status is ready; checkpoint after edits and before starting the run that builds them; 409 means a cloud build owns the sandbox or it is not running. Get a project by id. Returns one app: its status, publication state, preview and production URLs, and its latest run. Endpoint: GET /ai-builder-api/projects/{projectId} (Version header: v3; source: v3/clientportal-ai-v3.json) OAuth scopes: clientportal-ai.readonly

ghl_clientportal_update_projectB

CLIENT PORTAL AI BUILDER API (/ai-builder-api) — side-effecting: opens/edits sandboxes and starts builds. Edit a sandbox only once sandbox.status is ready; checkpoint after edits and before starting the run that builds them; 409 means a cloud build owns the sandbox or it is not running. Rename an app, archive it, or pin it to the top of the app list. Renames the app, archives it or brings it back, or pins it to the top of the app list. Send only the fields to change. Endpoint: PATCH /ai-builder-api/projects/{projectId} (Version header: v3; source: v3/clientportal-ai-v3.json) OAuth scopes: clientportal-ai.write

ghl_clientportal_list_projectsB

CLIENT PORTAL AI BUILDER API (/ai-builder-api) — side-effecting: opens/edits sandboxes and starts builds. Edit a sandbox only once sandbox.status is ready; checkpoint after edits and before starting the run that builds them; 409 means a cloud build owns the sandbox or it is not running. List projects in the caller's location. Lists the ClientPortal apps in the sub-account, most recently active first. A sub-account token sees every app by default; view=mine limits the list to apps the caller created. Endpoint: GET /ai-builder-api/projects (Version header: v3; source: v3/clientportal-ai-v3.json) OAuth scopes: clientportal-ai.readonly Pagination params: limit, cursor — pass them to page through full result sets.

ghl_clientportal_create_projectA

CLIENT PORTAL AI BUILDER API (/ai-builder-api) — side-effecting: opens/edits sandboxes and starts builds. Edit a sandbox only once sandbox.status is ready; checkpoint after edits and before starting the run that builds them; 409 means a cloud build owns the sandbox or it is not running. Create a project. Creates an app in the sub-account. Then start its first build with POST .../agent-runs; a sub-account token sends externalAgent: true because its own agent writes the code. Endpoint: POST /ai-builder-api/projects (Version header: v3; source: v3/clientportal-ai-v3.json) OAuth scopes: clientportal-ai.write

ghl_company_getA

REQUIRES AN AGENCY-LEVEL (Company) TOKEN — spec security is Agency-Access-Only. Get Company Get Comapny Endpoint: GET /companies/{companyId} (Version header: v3; source: v3/companies-v3.json) Requires an Agency (company-level) token. OAuth scopes: companies.readonly

ghl_contact_get_appointmentsB

Renamed from the auto-generated 'ghl_contact_get_appointments_for' (truncated trailing word). Get Appointments for Contact Endpoint: GET /contacts/{contactId}/appointments (Version header: v3; source: v3/contacts-v3.json) OAuth scopes: contacts.readonly

ghl_contact_remove_from_campaignB

Remove Contact From Campaign Endpoint: DELETE /contacts/{contactId}/campaigns/{campaignId} (Version header: v3; source: v3/contacts-v3.json) OAuth scopes: contacts.write

ghl_contact_add_to_campaignA

Adds a contact to one specific campaign. Empty request body (path params only). Add Contact to Campaign Add contact to Campaign Endpoint: POST /contacts/{contactId}/campaigns/{campaignId} (Version header: v3; source: v3/contacts-v3.json) OAuth scopes: contacts.write

ghl_contact_remove_from_all_campaignsA

v3-preferred variant of removing a contact from every campaign (kebab-case path, v3/contacts-v3.json). Renamed from the auto-generated 'ghl_contact_remove_from_every_campaign_delete2' (an ugly auto-suffix produced because it collided with the legacy op's derived name). Remove Contact From Every Campaign Removes the contact from every campaign it is enrolled in. Endpoint: DELETE /contacts/{contactId}/campaigns/remove-all (Version header: v3; source: v3/contacts-v3.json) OAuth scopes: contacts.write

ghl_contact_remove_followersB

Remove Followers Endpoint: DELETE /contacts/{contactId}/followers (Version header: v3; source: v3/contacts-v3.json) OAuth scopes: contacts.write

ghl_contact_add_followersB

Add Followers Endpoint: POST /contacts/{contactId}/followers (Version header: v3; source: v3/contacts-v3.json) OAuth scopes: contacts.write

ghl_contact_delete_noteB

Delete Note Endpoint: DELETE /contacts/{contactId}/notes/{id} (Version header: v3; source: v3/contacts-v3.json) OAuth scopes: contacts.write

ghl_contact_get_noteB

Get Note Endpoint: GET /contacts/{contactId}/notes/{id} (Version header: v3; source: v3/contacts-v3.json) OAuth scopes: contacts.readonly

ghl_contact_update_noteB

Update Note Endpoint: PUT /contacts/{contactId}/notes/{id} (Version header: v3; source: v3/contacts-v3.json) OAuth scopes: contacts.write

ghl_contact_get_all_notesB

Get All Notes Endpoint: GET /contacts/{contactId}/notes (Version header: v3; source: v3/contacts-v3.json) OAuth scopes: contacts.readonly

ghl_contact_create_noteB

Create Note Endpoint: POST /contacts/{contactId}/notes (Version header: v3; source: v3/contacts-v3.json) OAuth scopes: contacts.write

ghl_contact_remove_tagsB

Remove Tags Endpoint: DELETE /contacts/{contactId}/tags (Version header: v3; source: v3/contacts-v3.json) OAuth scopes: contacts.write

ghl_contact_add_tagsC

Add Tags Endpoint: POST /contacts/{contactId}/tags (Version header: v3; source: v3/contacts-v3.json) OAuth scopes: contacts.write

ghl_contact_update_task_completedB

Update Task Completed Endpoint: PUT /contacts/{contactId}/tasks/{taskId}/completed (Version header: v3; source: v3/contacts-v3.json) OAuth scopes: contacts.write

ghl_contact_delete_taskC

Delete Task Endpoint: DELETE /contacts/{contactId}/tasks/{taskId} (Version header: v3; source: v3/contacts-v3.json) OAuth scopes: contacts.write

ghl_contact_get_taskA

Get Task Endpoint: GET /contacts/{contactId}/tasks/{taskId} (Version header: v3; source: v3/contacts-v3.json) OAuth scopes: contacts.readonly

ghl_contact_update_taskA

REGRESSION-VERIFIED: assignedTo is present in UpdateTaskBody. Unlike create, no fields are marked required on update — all of title/body/dueDate/completed/assignedTo are optional partial updates. Update Task Endpoint: PUT /contacts/{contactId}/tasks/{taskId} (Version header: v3; source: v3/contacts-v3.json) OAuth scopes: contacts.write

ghl_contact_get_all_tasksB

Get all Tasks Endpoint: GET /contacts/{contactId}/tasks (Version header: v3; source: v3/contacts-v3.json) OAuth scopes: contacts.readonly

ghl_contact_create_taskA

REGRESSION-VERIFIED: assignedTo is present in CreateTaskParams. The old connector's create_task always 422'd — per the spec (v3/contacts-v3.json CreateTaskParams.required), title, dueDate, and completed are ALL required on create (not just title), and dueDate must be ISO 8601 (e.g. 2020-10-25T11:00:00Z). Passing completed:false is required even though it reads oddly for a brand-new task — that's what the spec mandates. Create Task Endpoint: POST /contacts/{contactId}/tasks (Version header: v3; source: v3/contacts-v3.json) OAuth scopes: contacts.write

ghl_contact_delete_from_workflowB

Delete Contact from Workflow Endpoint: DELETE /contacts/{contactId}/workflow/{workflowId} (Version header: v3; source: v3/contacts-v3.json) OAuth scopes: contacts.write

ghl_contact_add_to_workflowB

Add Contact to Workflow Endpoint: POST /contacts/{contactId}/workflow/{workflowId} (Version header: v3; source: v3/contacts-v3.json) OAuth scopes: contacts.write

ghl_contact_deleteB

Delete Contact Endpoint: DELETE /contacts/{contactId} (Version header: v3; source: v3/contacts-v3.json) OAuth scopes: contacts.write

ghl_contact_get_by_idA

Fetches a single contact by ID. Distinct from ghl_contact_list (GET /contacts/, deprecated list) and ghl_contact_search_advanced (POST /contacts/search, filtered search) — renamed from the auto-generated 'ghl_contact_get_get2' (a collision-resolution artifact) for clarity per the audit brief's explicit ambiguity callout. Get Contact Retrieves a contact by its unique identifier. Endpoint: GET /contacts/{contactId} (Version header: v3; source: v3/contacts-v3.json) OAuth scopes: contacts.readonly

ghl_contact_updateA

REGRESSION-VERIFIED: body schema (UpdateContactDtoV3, v3/contacts-v3.json) includes assignedTo, customFields, tags, dnd, dndSettings, inboundDndSettings, address1, city, state, postalCode, country, dateOfBirth, source, website, timezone — all confirmed present against the raw spec, matching what the old connector was missing. tags on this endpoint overwrites the full tag list; use ghl_contact_add_tags/ghl_contact_remove_tags for incremental changes. Update Contact Update a contact using contactId

⚠️ When updating additional emails/phones, always include the current primary email/phone in the same request. Otherwise, the existing primary value may be lost. Endpoint: PUT /contacts/{contactId} (Version header: v3; source: v3/contacts-v3.json) OAuth scopes: contacts.write

ghl_contact_add_remove_from_businessC

Add/Remove Contacts From Business Add/Remove Contacts From Business . Passing a null businessId will remove the businessId from the contacts Endpoint: POST /contacts/bulk/business (Version header: v3; source: v3/contacts-v3.json)

ghl_contact_bulk_update_tagsA

Bulk add/remove tags across a list of contacts (path param type selects add|remove semantics per the API). Renamed from the auto-generated 'ghl_contact_create_association' — that name was simply wrong; this operation has nothing to do with the associations domain (custom relationships between object types). Body requires contacts, tags, locationId; removeAllTags is an optional bulk-remove-all flag. Update Contacts Tags Allows you to update tags to multiple contacts at once, you can add or remove tags from the contacts Endpoint: POST /contacts/bulk/tags/update/{type} (Version header: v3; source: v3/contacts-v3.json)

ghl_contact_get_by_business_idA

Get Contacts By BusinessId Endpoint: GET /contacts/business/{businessId} (Version header: v3; source: v3/contacts-v3.json) OAuth scopes: contacts.readonly Pagination params: limit, skip, startAfter — pass them to page through full result sets.

ghl_contact_lookupA

Lookup Contact By Email Or Phone Look up contacts matching an exact email or phone, scoped to a location, up to limit contacts (max 20) per page. Also matches against a contact's additional emails and additional phone numbers. Exactly one of email or phone must be provided. Paginate with nextCursor. Returns an empty contacts array if no contact matches. OAuth channel only. Endpoint: GET /contacts/lookup (Version header: v3; source: v3/contacts-v3.json) OAuth scopes: contacts.readonly Pagination params: limit — pass them to page through full result sets.

ghl_contact_createB

Create Contact Create a new contact Endpoint: POST /contacts/ (Version header: v3; source: v3/contacts-v3.json) OAuth scopes: contacts.write

ghl_contact_get_duplicateA

Neither number nor email is marked required by the spec, but at least one must be supplied for the lookup to return anything meaningful — this is a business-logic constraint the OpenAPI doesn't encode, not a bug in extraction. Both params must be URL-encoded (see each param's spec description/example). Get Duplicate Contact Get Duplicate Contact.If Allow Duplicate Contact is disabled under Settings, the global unique identifier will be used for searching the contact. If the setting is enabled, first priority for search is email and the second priority will be phone. Endpoint: GET /contacts/search/duplicate (Version header: v3; source: v3/contacts-v3.json) OAuth scopes: contacts.readonly

ghl_contact_search_advancedA

SPEC GAP: the official OpenAPI's SearchBodyV2DTO is an empty object schema — GoHighLevel's spec only points to an external ClickUp doc (linked in the op's externalDocs) for the real filter/sort/pageLimit/searchAfter/query body shape, which is not available in this docs corpus. Verified this is a genuine spec gap (not an extraction bug) against both the legacy (contacts.json) and v3 (v3/contacts-v3.json) copies of this endpoint, and via ghl_docs_context — both show the identical empty schema. The generated tool's body property will still accept arbitrary JSON (no additionalProperties:false is applied inside body sub-schemas), so callers who know the real field names from GHL's docs can pass them; there's just no schema-level validation or autocomplete for this one operation. Search Contacts Search contacts based on combinations of advanced filters. Documentation Link - https://doc.clickup.com/8631005/d/h/87cpx-158396/6e629989abe7fad Endpoint: POST /contacts/search (Version header: v3; source: v3/contacts-v3.json) OAuth scopes: contacts.readonly

ghl_contact_upsertA

Requires locationId. Same field set as ghl_contact_create; use createNewIfDuplicateAllowed to control dedup behavior. Upsert Contact The Upsert API will adhere to the configuration defined under the "Allow Duplicate Contact" setting at the Location level. If the setting is configured to check both Email and Phone, the API will attempt to identify an existing contact based on the priority sequence specified in the setting, and will create or update the contact accordingly.If two separate contacts already exist—one with the same email and another with the same phone—and an upsert request includes both the email and phone, the API will update the contact that matches the first field in the configured sequence, and ignore the second field to prevent duplication. Endpoint: POST /contacts/upsert (Version header: v3; source: v3/contacts-v3.json) OAuth scopes: contacts.write

ghl_conversation_ai_delete_actionA

Remove Action from Agent Permanently deletes an action. This will remove the action from all associated agents and cannot be undone. Applies to both classic and customApi ("API Call") actions. Endpoint: DELETE /conversation-ai/agents/{agentId}/actions/{actionId} (Version header: v3; source: v3/conversation-ai-v3.json) OAuth scopes: conversation-ai.write

ghl_conversation_ai_get_action_by_idA

Get Action by ID Retrieves detailed information about a specific action using its unique identifier. Returns the action configuration, associated agents, and performance metrics. Supports both classic actions and the customApi ("API Call") type. Endpoint: GET /conversation-ai/agents/{agentId}/actions/{actionId} (Version header: v3; source: v3/conversation-ai-v3.json) OAuth scopes: conversation-ai.readonly

ghl_conversation_ai_update_actionA

Update Action Updates an existing action's configuration — name, description, trigger condition and behaviour settings. For customApi ("API Call") actions details.apiConfig is optional: omit it to leave the HTTP definition untouched. When sent, it is merged ONE LEVEL DEEP over the stored config — a top-level key you send replaces the stored value outright, keys you omit are kept. Nested values (headers, queryParams, bodyTemplate, parameters, outputFields) are replaced whole, so send the complete object rather than just the entry you changed. authentication is the exception: secret fields omitted, or returned as the redacted placeholder, keep the stored secret. Endpoint: PUT /conversation-ai/agents/{agentId}/actions/{actionId} (Version header: v3; source: v3/conversation-ai-v3.json) OAuth scopes: conversation-ai.write

ghl_conversation_ai_list_actionsA

[DEPRECATED per official docs — prefer the documented replacement if one exists.] List Actions for an Agent Deprecated — use GET /conversation-ai/agents/{agentId}/actions instead. List for actions for an agent, including any customApi ("API Call") actions. Endpoint: GET /conversation-ai/agents/{agentId}/actions/list (Version header: v3; source: v3/conversation-ai-v3.json) OAuth scopes: conversation-ai.readonly

ghl_conversation_ai_get_agent_actionsA

List Actions for an Agent List for actions for an agent, including any customApi ("API Call") actions. Endpoint: GET /conversation-ai/agents/{agentId}/actions (Version header: v3; source: v3/conversation-ai-v3.json) OAuth scopes: conversation-ai.readonly

ghl_conversation_ai_create_actionA

Attach Action to Agent Creates and attach a new action for an AI agent. Actions define specific tasks or behaviors that the agent can perform, such as booking appointments, sending follow-ups, collecting information, or making an external API call via the customApi ("API Call") type. For customApi, put the config in details (details.apiConfig is required) and a per-agent limit (up to 5) applies. Endpoint: POST /conversation-ai/agents/{agentId}/actions (Version header: v3; source: v3/conversation-ai-v3.json) OAuth scopes: conversation-ai.write

ghl_conversation_ai_update_followup_settingsB

Update Followup Settings Update the followup settings for an action Endpoint: PATCH /conversation-ai/agents/{agentId}/followup-settings (Version header: v3; source: v3/conversation-ai-v3.json) OAuth scopes: conversation-ai.write

ghl_conversation_ai_delete_agent_working_hoursA

Delete Agent Working Hours Deletes the working-hours configuration for an AI agent. The agent then replies at any time. Succeeds with deleted=false when there was nothing to delete. Endpoint: DELETE /conversation-ai/agents/{agentId}/working-hours (Version header: v3; source: v3/conversation-ai-v3.json) OAuth scopes: conversation-ai.write

ghl_conversation_ai_get_agent_working_hoursA

Get Agent Working Hours Retrieves the working-hours configuration for an AI agent: the weekly schedule, the channels it applies to, the timezone mode, and the off-hours auto-reply and follow-up settings. Endpoint: GET /conversation-ai/agents/{agentId}/working-hours (Version header: v3; source: v3/conversation-ai-v3.json) OAuth scopes: conversation-ai.readonly

ghl_conversation_ai_create_agent_working_hoursA

Create Agent Working Hours Creates the working-hours configuration for an AI agent. Returns 409 when one already exists — use the update endpoint to replace it. Endpoint: POST /conversation-ai/agents/{agentId}/working-hours (Version header: v3; source: v3/conversation-ai-v3.json) OAuth scopes: conversation-ai.write

ghl_conversation_ai_update_agent_working_hoursA

Update Agent Working Hours Fully replaces the working-hours configuration for an AI agent. Returns 404 when none exists yet — use the create endpoint first. This is a replace, not a merge: omitted fields are not preserved. Endpoint: PUT /conversation-ai/agents/{agentId}/working-hours (Version header: v3; source: v3/conversation-ai-v3.json) OAuth scopes: conversation-ai.write

ghl_conversation_ai_delete_agentA

Delete Agent Deletes an AI agent permanently. This action cannot be undone. All associated configurations and conversation history will be removed. Endpoint: DELETE /conversation-ai/agents/{agentId} (Version header: v3; source: v3/conversation-ai-v3.json) OAuth scopes: conversation-ai.write

ghl_conversation_ai_get_agentA

Get Agent Retrieves a specific AI agent by its ID. Returns the complete agent configuration including name, status, actions, and settings. Endpoint: GET /conversation-ai/agents/{agentId} (Version header: v3; source: v3/conversation-ai-v3.json) OAuth scopes: conversation-ai.readonly

ghl_conversation_ai_update_agentA

Update Agent Updates an existing AI agent's configuration. All fields in the agent configuration can be updated including name, status, actions, and behavior settings. Endpoint: PUT /conversation-ai/agents/{agentId} (Version header: v3; source: v3/conversation-ai-v3.json) OAuth scopes: conversation-ai.write

ghl_conversation_ai_search_agentA

Search Agents Searches for AI agents based on various criteria including name, status, and configuration. Supports advanced filtering and full-text search capabilities. Endpoint: GET /conversation-ai/agents/search (Version header: v3; source: v3/conversation-ai-v3.json) OAuth scopes: conversation-ai.readonly Pagination params: startAfter, limit — pass them to page through full result sets.

ghl_conversation_ai_create_agentB

Create an Agent Creates a new AI agent for the location. The agent will be created with the specified configuration including name, role, actions, and behavior settings. Endpoint: POST /conversation-ai/agents (Version header: v3; source: v3/conversation-ai-v3.json) OAuth scopes: conversation-ai.write

ghl_conversation_ai_get_generationA

Get the generation details Retrieves detailed information about AI responses including the System Prompt, Conversation history, Knowledge base, website, FAQ chunks, and Rich Text chunks. Endpoint: GET /conversation-ai/generations (Version header: v3; source: v3/conversation-ai-v3.json) OAuth scopes: conversation-ai.readonly

ghl_conversation_get_messagesA

Get messages by conversation id Get messages by conversation id. Endpoint: GET /conversations/{conversationId}/messages (Version header: v3; source: v3/conversations-v3.json) OAuth scopes: conversations/message.readonly Pagination params: lastMessageId, limit — pass them to page through full result sets.

ghl_conversation_deleteB

Delete Conversation Delete the conversation details based on the conversation ID Endpoint: DELETE /conversations/{conversationId} (Version header: v3; source: v3/conversations-v3.json) OAuth scopes: conversations.write

ghl_conversation_getB

Get Conversation Get the conversation details based on the conversation ID Endpoint: GET /conversations/{conversationId} (Version header: v3; source: v3/conversations-v3.json) OAuth scopes: conversations.readonly

ghl_conversation_updateB

Update Conversation Update the conversation details based on the conversation ID Endpoint: PUT /conversations/{conversationId} (Version header: v3; source: v3/conversations-v3.json) OAuth scopes: conversations.write

ghl_conversation_download_message_transcriptionA

Response is NOT JSON — returns the transcription as a text/plain file download (Content-Disposition: attachment; filename="transcription.txt") per the spec's response headers, distinct from GET .../transcription (no /download) which returns a normal JSON object. Download transcription by Message ID Download the recording transcription for a message by passing the message id Endpoint: GET /conversations/locations/{locationId}/messages/{messageId}/transcription/download (Version header: v3; source: v3/conversations-v3.json) Requires a Sub-Account (location) token.

ghl_conversation_get_message_transcriptionA

Get transcription by Message ID Get the recording transcription for a message by passing the message id Endpoint: GET /conversations/locations/{locationId}/messages/{messageId}/transcription (Version header: v3; source: v3/conversations-v3.json) Requires a Sub-Account (location) token.

ghl_conversation_get_messageA

Note: the official spec omits the id path-parameter declaration; this server infers it from the URL template (registry.ts fallback added 2026-07-16), so id (the message ID) is a required argument here despite the spec gap. Get message by message id Get message by message id. Endpoint: GET /conversations/messages/{id} (Version header: v3; source: v3/conversations-v3.json) OAuth scopes: conversations/message.readonly

ghl_conversation_add_message_attachmentsA

Replaces/adds attachments (URLs) on an existing message — separate from POST /conversations/messages/upload, which is the file-binary upload step that produces those URLs. Add message attachments Set attachments on an existing message (replaces existing). Maximum 5 URLs. Supported for Custom Call message type. Endpoint: PUT /conversations/messages/{messageId}/attachments (Version header: v3; source: v3/conversations-v3.json) OAuth scopes: conversations/message.write

ghl_conversation_get_message_recordingA

Response is NOT JSON — returns the raw recording as audio/x-wav (Content-Disposition: attachment; filename=audio.wav) per the spec's response headers. Callers must handle a binary/audio body, not a parsed JSON object. Get Recording by Message ID Get the recording for a message by passing the message id Endpoint: GET /conversations/messages/{messageId}/locations/{locationId}/recording (Version header: v3; source: v3/conversations-v3.json) Requires a Sub-Account (location) token.

ghl_conversation_cancel_scheduled_messageA

Cancel a scheduled message. Post the messageId for the API to delete a scheduled message. Endpoint: DELETE /conversations/messages/{messageId}/schedule (Version header: v3; source: v3/conversations-v3.json) OAuth scopes: conversations/message.write

ghl_conversation_update_message_statusC

Update message status Post the necessary fields for the API to update message status. Endpoint: PUT /conversations/messages/{messageId}/status (Version header: v3; source: v3/conversations-v3.json) OAuth scopes: conversations/message.write

ghl_conversation_cancel_scheduled_email_messageB

Cancel a scheduled email message. Post the messageId for the API to delete a scheduled email message. Endpoint: DELETE /conversations/messages/email/{emailMessageId}/schedule (Version header: v3; source: v3/conversations-v3.json) OAuth scopes: conversations/message.write

ghl_conversation_update_email_message_statusA

Update email message status Update delivery events, per-recipient statuses, and the overall message status for an email sent via a custom conversation provider.

Authorization

  • Requires the conversations/message.write OAuth scope.

  • The calling OAuth app must own the conversation provider that originally sent the email.

  • Attempts to update emails sent via LC Email or Mailgun will return 403 Forbidden.

Updatable Fields

All request body fields are optional. Pass only what you need to update.

events — Aggregate delivery event counters (integers). Counters are merged into the existing values (not replaced). Setting a counter to 0 is treated as no-op and will not reset the stored value.

recipients — Per-recipient delivery statuses. Each entry maps a recipient email address to a MessageStatus value. Use failReason to capture bounce or rejection details when the status is failed.

status — The overall message status. Accepts any MessageStatus enum value.

Event Inference

The API automatically infers related events to maintain data consistency:

  • clicked, complained, unsubscribed, or replied → implies opened (set to 1 if not already provided and open tracking is enabled) and delivered (set to 1).

  • opened → implies delivered (set to 1 if not provided).

  • delivered, permanent_fail, or temporary_fail → implies accepted (set to 1 if not provided).

Timestamps

The API automatically records server-side timestamps on first oc Endpoint: PUT /conversations/messages/email/{emailMessageId}/status (Version header: v3; source: v3/conversations-v3.json) OAuth scopes: conversations/message.write

ghl_conversation_get_email_messageA

Note: the official spec omits the id path-parameter declaration; this server infers it from the URL template (registry.ts fallback added 2026-07-16), so id (the email message ID) is a required argument here despite the spec gap. Get email by Id Endpoint: GET /conversations/messages/email/{id} (Version header: v3; source: v3/conversations-v3.json) OAuth scopes: conversations/message.readonly

ghl_conversation_export_messages_by_locationA

Export messages by location ID Export messages for a specific location with cursor-based pagination support.

Channel Filtering Behavior:

  • When channel is omitted: Returns all non-email message types, including messages that don't belong to any specific channel.

  • When channel=Email: Returns email messages only.

  • When channel is specified (SMS, Call, WhatsApp, etc.): Returns messages for that specific channel.

Limitations:

  • Group Chat and SMS Review Request message types are not supported.

  • Activity messages (opportunity updates, appointments, etc.) are not included in the export. Use GET /conversations/{conversationId}/messages (Get messages by conversation id) to fetch them.

  • Cursor validity is 2 minutes from the last request made. Endpoint: GET /conversations/messages/export (Version header: v3; source: v3/conversations-v3.json) OAuth scopes: conversations/message.readonly Pagination params: limit, cursor — pass them to page through full result sets.

ghl_conversation_add_inbound_messageA

Add an inbound message Post the necessary fields for the API to add a new inbound message. Note: Either conversationId or contactId is required Endpoint: POST /conversations/messages/inbound (Version header: v3; source: v3/conversations-v3.json) OAuth scopes: conversations/message.write

ghl_conversation_add_outbound_messageB

Add an external outbound call Post the necessary fields for the API to add a new outbound call. Endpoint: POST /conversations/messages/outbound (Version header: v3; source: v3/conversations-v3.json) OAuth scopes: conversations/message.write

ghl_conversation_upload_file_attachmentsA

multipart/form-data upload. The body schema below carries only the declared form fields (conversationId, contactId, locationId, attachmentUrls, chatServiceSid, isGroupSms) from UploadFilesDto — per the endpoint description, each file's binary content must ALSO be attached as a separate multipart part keyed fileAttachment (buffer), which is not represented in the JSON schema. Allowed file types per spec: JPG, JPEG, PNG, MP4, MPEG, ZIP, RAR, PDF, DOC, DOCX, TXT, MP3, WAV. Upload file attachments Post the necessary fields for the API to upload files. The files need to be a buffer with the key "fileAttachment". Note: One of conversationId or contactId must be provided. File Size Limits: Maximum file size: 5 MBMaximum files per upload: 5 Allowed file types: Images: JPG, JPEG, PNG, GIF, SVG, HEIC, AI Videos: MP4, MPEG, 3GP Audio: MP3, WAV, WAVE, AIFF, AIF, AIFC, GSM, ULAW, OGG, AAC, M4A, AMR Documents: PDF, DOC, DOCX, TXT, CSV, XLS, XLSX, PPT, PPTX, ODT Archives: ZIP, RAR Other: VCF, VCARD (contact files), ICS (calendar files) The API will return an object with the URLs Secure attachments: Set isSecureAttachment to true to upload the file as a secure attachment. This is currently supported for the email channel only; support for the remaining conversation channels is coming. A secure attachment is returned with a /files/d/{slug} URL that is publicly accessible for one hour after upload. After that window the attachment becomes private — to render, download, or retry access, extract the {slug} from the returned URL and call GET /files/d/{slug} with a bearer token Endpoint: POST /conversations/messages/upload (Version header: v3; source: v3/conversations-v3.json) OAuth scopes: conversations/message.write

ghl_conversation_send_messageA

PHI-adjacent: sends a message on a real conversation thread. DELIBERATE OVERRIDE of the broken upstream spec (2026-08-26): the official conversations-v3.json declares subType as an empty object schema (the live API validates it as a string enum, so {} 422s with 'subType must be a valid enum value') and marks [type, subType, contactId, status] as required (forcing subType/status is what makes every call fail — a plain SMS needs only type + contactId + message). This tool therefore requires only type and contactId; subType and status are optional strings and are OMITTED from the outbound request entirely when not supplied (the API validates the key if present). The spec enumerates no valid subType values — pass one only if you know it from GHL docs. Populate type-appropriate fields alongside: message (+ fromNumber/toNumber) for SMS-style channels; html/subject/emailTo/emailCc for Email; attachments as URLs. If the spec extractor is re-run, keep this patchBody override — do not let regeneration silently restore the broken schema. Send a new message Post the necessary fields for the API to send a new message. Endpoint: POST /conversations/messages (Version header: v3; source: v3/conversations-v3.json) OAuth scopes: conversations/message.write

ghl_conversation_createB

Create Conversation Creates a new conversation with the data provided Endpoint: POST /conversations/ (Version header: v3; source: v3/conversations-v3.json) OAuth scopes: conversations.write

ghl_conversation_live_chat_agent_typingB

Agent/Ai-Bot is typing a message indicator for live chat Agent/AI-Bot will call this when they are typing a message in live chat message Endpoint: POST /conversations/providers/live-chat/typing (Version header: v3; source: v3/conversations-v3.json) Requires a Sub-Account (location) token. OAuth scopes: conversations/livechat.write

ghl_conversation_searchA

Search Conversations Returns a list of all conversations matching the search criteria along with the sort and filter options selected. Endpoint: GET /conversations/search (Version header: v3; source: v3/conversations-v3.json) OAuth scopes: conversations.readonly Pagination params: limit — pass them to page through full result sets.

ghl_countdown_list_timer_templatesA

COUNTDOWN TIMER API — timers belong to the access token's location. List Timer Templates Get the available countdown timer templates with their default design configuration Endpoint: GET /countdown-timer/templates (Version header: v3; source: v3/countdown-timer-v3.json) Requires a Sub-Account (location) token. OAuth scopes: countdown-timer/timer.readonly

ghl_countdown_delete_timerA

COUNTDOWN TIMER API — timers belong to the access token's location. Delete Countdown Timer Soft-delete a countdown timer Endpoint: DELETE /countdown-timer/timers/{timerId} (Version header: v3; source: v3/countdown-timer-v3.json) Requires a Sub-Account (location) token. OAuth scopes: countdown-timer/timer.write

ghl_countdown_get_timerA

COUNTDOWN TIMER API — timers belong to the access token's location. Get Countdown Timer Get a countdown timer by ID Endpoint: GET /countdown-timer/timers/{timerId} (Version header: v3; source: v3/countdown-timer-v3.json) Requires a Sub-Account (location) token. OAuth scopes: countdown-timer/timer.readonly

ghl_countdown_update_timerB

COUNTDOWN TIMER API — timers belong to the access token's location. Update Countdown Timer Update an existing countdown timer Endpoint: PATCH /countdown-timer/timers/{timerId} (Version header: v3; source: v3/countdown-timer-v3.json) Requires a Sub-Account (location) token. OAuth scopes: countdown-timer/timer.write

ghl_countdown_list_timersA

COUNTDOWN TIMER API — timers belong to the access token's location. List Countdown Timers Get a paginated list of the countdown timers belonging to the access token's location Endpoint: GET /countdown-timer/timers (Version header: v3; source: v3/countdown-timer-v3.json) Requires a Sub-Account (location) token. OAuth scopes: countdown-timer/timer.readonly Pagination params: limit, skip — pass them to page through full result sets.

ghl_countdown_create_timerA

COUNTDOWN TIMER API — timers belong to the access token's location. Create Countdown Timer Create a countdown timer for the access token's location Endpoint: POST /countdown-timer/timers (Version header: v3; source: v3/countdown-timer-v3.json) Requires a Sub-Account (location) token. OAuth scopes: countdown-timer/timer.write

ghl_course_importC

COURSES API — the {productId} path parameter is the course (product) id. Import Courses Import Courses through public channels Endpoint: POST /courses/courses-exporter/public/import (Version header: v3; source: v3/courses-v3.json)

ghl_course_delete_enrollmentA

COURSES API — the {productId} path parameter is the course (product) id. Revoke Enrollment Revoke a contact from a membership offer. Requires a Location token with courses.write. Send Version: v3. Uses DELETE smart-list/user (offer revoke, not product blacklist). Sibling products on the same offer are also revoked. Default-offer rows return 404. Endpoint: DELETE /courses/enrollments (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.write

ghl_course_create_enrollmentA

COURSES API — the {productId} path parameter is the course (product) id. Enroll Contact Grant a contact access to a membership offer. Requires a Location token with courses.write. Send Version: v3. Uses POST smart-list/user with source public_api (not the queued attach-offer-user path). Returns 200 when already enrolled and 201 when newly attached. Login tokens are never returned. checkoutFrom public_api is not in membership paidSources, so these grants are omitted from Net Revenue paid filters. Default-offer rows return 404. Endpoint: POST /courses/enrollments (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.write

ghl_course_delete_offerA

COURSES API — the {productId} path parameter is the course (product) id. Delete Offer Delete a membership offer. Requires a Location token with courses.write. Send Version: v3. Endpoint: DELETE /courses/offers/{offerId} (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.write

ghl_course_get_offerA

COURSES API — the {productId} path parameter is the course (product) id. Get Offer Get a membership offer by id. Requires a Location token with courses.readonly. Send Version: v3. Default-offer rows (source other than membership) return 404. Endpoint: GET /courses/offers/{offerId} (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.readonly

ghl_course_update_offerB

COURSES API — the {productId} path parameter is the course (product) id. Update Offer Update a membership offer. Requires a Location token with courses.write. Send Version: v3. Returns the full offer. locationId, id, userId, originId, and addProductToMembers are not accepted. Endpoint: PUT /courses/offers/{offerId} (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.write

ghl_course_list_offersA

COURSES API — the {productId} path parameter is the course (product) id. List Offers List membership offers in the location. Requires a Location token with courses.readonly. Send Version: v3. Uses membership listView pagination (cursor encodes skip). Location-wide — membership does not filter by productId. Default-offer rows are not included. Endpoint: GET /courses/offers (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.readonly Pagination params: limit, cursor — pass them to page through full result sets.

ghl_course_create_offerA

COURSES API — the {productId} path parameter is the course (product) id. Create Offer Create a membership offer. Requires a Location token with courses.write. Send Version: v3. Returns the full offer. source is always membership. locationId, userId, originId, and addProductToMembers are not accepted. Non-free type still requires payment integrations upstream. Endpoint: POST /courses/offers (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.write

ghl_course_review_assessmentA

COURSES API — the {productId} path parameter is the course (product) id. Review Assessment Review an assessment submission. Requires a Location token with courses.write. Send Version: v3. Location tokens are not a staff reviewer. Endpoint: PUT /courses/products/{productId}/assessments/{assessmentId}/review (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.write

ghl_course_get_assessmentA

COURSES API — the {productId} path parameter is the course (product) id. Get Assessment Get one assessment submission. Requires a Location token with courses.readonly. Send Version: v3. Endpoint: GET /courses/products/{productId}/assessments/{assessmentId} (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.readonly

ghl_course_list_assessmentsA

COURSES API — the {productId} path parameter is the course (product) id. List Assessments List assessment submissions for a course. Requires a Location token with courses.readonly. Send Version: v3. Endpoint: GET /courses/products/{productId}/assessments (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.readonly Pagination params: pageSize — pass them to page through full result sets.

ghl_course_delete_assignmentA

COURSES API — the {productId} path parameter is the course (product) id. Delete Assignment Delete an assignment. Requires a Location token with courses.write. Send Version: v3. Endpoint: DELETE /courses/products/{productId}/assignments/{assignmentId} (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.write

ghl_course_update_assignmentA

COURSES API — the {productId} path parameter is the course (product) id. Update Assignment Update an assignment. Requires a Location token with courses.write. Send Version: v3. Endpoint: PUT /courses/products/{productId}/assignments/{assignmentId} (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.write

ghl_course_sequence_lessonsA

COURSES API — the {productId} path parameter is the course (product) id. Sequence Lessons Reorder lessons in a category. Requires a Location token with courses.write. Endpoint: PUT /courses/products/{productId}/categories/{categoryId}/lessons/sequence (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.write

ghl_course_delete_categoryA

COURSES API — the {productId} path parameter is the course (product) id. Delete Category Delete a category. Requires a Location token with courses.write. Endpoint: DELETE /courses/products/{productId}/categories/{categoryId} (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.write

ghl_course_get_categoryA

COURSES API — the {productId} path parameter is the course (product) id. Get Category Get a category by id. Requires a Location token with courses.readonly. Returns the full category object. Endpoint: GET /courses/products/{productId}/categories/{categoryId} (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.readonly

ghl_course_update_categoryA

COURSES API — the {productId} path parameter is the course (product) id. Update Category Update a category. Requires a Location token with courses.write. Accepts the same category columns as create. All fields optional. Endpoint: PUT /courses/products/{productId}/categories/{categoryId} (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.write

ghl_course_list_category_progressA

COURSES API — the {productId} path parameter is the course (product) id. List Category Progress Return per-category progress for a contact in a product. Requires a Location token with courses.readonly. Send Version: v3. Endpoint: GET /courses/products/{productId}/categories/progress (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.readonly

ghl_course_sequence_categoriesA

COURSES API — the {productId} path parameter is the course (product) id. Sequence Categories Reorder categories in a course. Requires a Location token with courses.write. Endpoint: PUT /courses/products/{productId}/categories/sequence (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.write

ghl_course_list_categoriesA

COURSES API — the {productId} path parameter is the course (product) id. List Categories List categories for a course. Requires a Location token with courses.readonly. Each item is the full category object. Endpoint: GET /courses/products/{productId}/categories (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.readonly

ghl_course_create_categoryA

COURSES API — the {productId} path parameter is the course (product) id. Create Category Create a category in a course. Requires a Location token with courses.write. Accepts category columns (title required). locationId, userId, productId, originId are not accepted. Endpoint: POST /courses/products/{productId}/categories (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.write

ghl_course_list_completionsA

COURSES API — the {productId} path parameter is the course (product) id. List Completions With contactId, return that learner's completed lessons. Without contactId, return a paginated creator rollup by contact. Requires a Location token with courses.readonly. Send Version: v3. Endpoint: GET /courses/products/{productId}/completions (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.readonly Pagination params: pageSize — pass them to page through full result sets.

ghl_course_list_enrollmentsA

COURSES API — the {productId} path parameter is the course (product) id. List Product Enrollments List contacts enrolled in a product. Requires a Location token with courses.readonly. Send Version: v3. Reads user_purchases in the bound location. Does not return email or lesson progress. Cursor encodes createdAt and id. Endpoint: GET /courses/products/{productId}/enrollments (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.readonly Pagination params: limit, cursor — pass them to page through full result sets.

ghl_course_get_lesson_assignmentA

COURSES API — the {productId} path parameter is the course (product) id. Get Lesson Assignment Get the assignment for a lesson. Requires a Location token with courses.readonly. Send Version: v3. Endpoint: GET /courses/products/{productId}/lessons/{lessonId}/assignment (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.readonly

ghl_course_create_lesson_assignmentA

COURSES API — the {productId} path parameter is the course (product) id. Create Lesson Assignment Create an assignment on a lesson. Requires a Location token with courses.write. Send Version: v3. Path lessonId is sent to membership as postId. locationId, userId, and productId are not accepted in the body. Endpoint: POST /courses/products/{productId}/lessons/{lessonId}/assignment (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.write

ghl_course_get_lesson_quizA

COURSES API — the {productId} path parameter is the course (product) id. Get Lesson Quiz Get the quiz for a lesson. Requires a Location token with courses.readonly. Send Version: v3. Endpoint: GET /courses/products/{productId}/lessons/{lessonId}/quiz (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.readonly

ghl_course_create_lesson_quizA

COURSES API — the {productId} path parameter is the course (product) id. Create Lesson Quiz Create a quiz on a lesson. Requires a Location token with courses.write. Send Version: v3. Path lessonId is sent to membership as postId. locationId, userId, and productId are not accepted in the body. Endpoint: POST /courses/products/{productId}/lessons/{lessonId}/quiz (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.write

ghl_course_delete_lessonA

COURSES API — the {productId} path parameter is the course (product) id. Delete Lesson Delete a lesson. Requires a Location token with courses.write. Endpoint: DELETE /courses/products/{productId}/lessons/{lessonId} (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.write

ghl_course_get_lessonA

COURSES API — the {productId} path parameter is the course (product) id. Get Lesson Get a lesson by id. Requires a Location token with courses.readonly. Returns the full lesson object. Endpoint: GET /courses/products/{productId}/lessons/{lessonId} (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.readonly

ghl_course_update_lessonA

COURSES API — the {productId} path parameter is the course (product) id. Update Lesson Update a lesson. Requires a Location token with courses.write. Accepts the same lesson columns as create. All fields optional. Omit categoryId to keep the current category. Endpoint: PUT /courses/products/{productId}/lessons/{lessonId} (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.write

ghl_course_list_lessonsA

COURSES API — the {productId} path parameter is the course (product) id. List Lessons List lessons for a course. Pass categoryId to list one category; omit it to list every category (N+1 membership reads). Requires a Location token with courses.readonly. Each item is the full lesson object. Endpoint: GET /courses/products/{productId}/lessons (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.readonly

ghl_course_create_lessonA

COURSES API — the {productId} path parameter is the course (product) id. Create Lesson Create a lesson. Requires title and categoryId. Accepts lesson columns. locationId, userId, productId, originId are not accepted. Requires a Location token with courses.write. Endpoint: POST /courses/products/{productId}/lessons (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.write

ghl_course_get_quiz_questionsA

COURSES API — the {productId} path parameter is the course (product) id. List Quiz Questions List questions for a quiz. Requires a Location token with courses.readonly. Send Version: v3. Endpoint: GET /courses/products/{productId}/quizzes/{quizId}/questions (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.readonly

ghl_course_upsert_quiz_questionsA

COURSES API — the {productId} path parameter is the course (product) id. Replace Quiz Questions Batch upsert quiz questions. Requires a Location token with courses.write. Send Version: v3. quizId is taken from the path, not the body. Endpoint: PUT /courses/products/{productId}/quizzes/{quizId}/questions (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.write

ghl_course_delete_quizA

COURSES API — the {productId} path parameter is the course (product) id. Delete Quiz Delete a quiz. Requires a Location token with courses.write. Send Version: v3. Endpoint: DELETE /courses/products/{productId}/quizzes/{quizId} (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.write

ghl_course_update_quizA

COURSES API — the {productId} path parameter is the course (product) id. Update Quiz Update a quiz. Requires a Location token with courses.write. Send Version: v3. Endpoint: PUT /courses/products/{productId}/quizzes/{quizId} (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.write

ghl_course_deleteA

COURSES API — the {productId} path parameter is the course (product) id. Delete Course Delete a course. Requires a Location token with courses.write. Endpoint: DELETE /courses/products/{productId} (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.write

ghl_course_getA

COURSES API — the {productId} path parameter is the course (product) id. Get Course Get a course by id. Requires a Location token with courses.readonly. Returns product columns and nested customizations. Endpoint: GET /courses/products/{productId} (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.readonly

ghl_course_updateB

COURSES API — the {productId} path parameter is the course (product) id. Update Course Update a course. Requires a Location token with courses.write. Accepts the same product columns and nested customizations as create. All fields optional. Endpoint: PUT /courses/products/{productId} (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.write

ghl_course_listA

COURSES API — the {productId} path parameter is the course (product) id. List Courses List courses in the location. Requires a Location token with courses.readonly. Send Version: v3. Each item is the full course object including customizations. Endpoint: GET /courses/products (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.readonly Pagination params: limit, cursor — pass them to page through full result sets.

ghl_course_createA

COURSES API — the {productId} path parameter is the course (product) id. Create Course Create a course in the location. Requires a Location token with courses.write. Accepts product columns and nested customizations. locationId, userId, id, originId, source, and processing are not accepted. Endpoint: POST /courses/products (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.write

ghl_course_list_bulk_progressA

COURSES API — the {productId} path parameter is the course (product) id. List Product Progress Return progress for the given contact across productIds. Requires a Location token with courses.readonly. Send Version: v3. productIds is a comma-separated list of at most 50 UUID v4 product ids. Endpoint: GET /courses/progress (Version header: v3; source: v3/courses-v3.json) Requires a Sub-Account (location) token. OAuth scopes: courses.readonly

ghl_custom_field_deleteB

Delete Custom Field By Id

ghl_custom_field_get_by_idA

Also returns custom field FOLDERS by the same id (per the spec's own summary: 'Get Custom Field / Folder By Id') — check the response shape to tell which you got. Get Custom Field / Folder By Id

ghl_custom_field_updateA

Per spec (UpdateCustomFieldsDTO), locationId and showInForms are both required on every update call, even ones that only change name/description/options — this is a genuine spec requirement, not an extraction artifact. Update Custom Field By Id

ghl_custom_field_delete_folderC

Delete Custom Field Folder

ghl_custom_field_update_folderC

Update Custom Field Folder Name

ghl_custom_field_create_folderA

Create Custom Field Folder

ghl_custom_field_get_by_object_keyA

Get Custom Fields By Object Key

ghl_custom_field_createA

Create Custom Field

ghl_custom_menu_deleteA

REQUIRES AN AGENCY-LEVEL (Company) TOKEN — spec security is Agency-Access-Only for all custom-menus ops. Delete Custom Menu Link Removes a specific custom menu from the system. This operation requires authentication and proper permissions. The custom menu is identified by its unique ID, and the operation is performed within the context of a specific company. Endpoint: DELETE /custom-menus/{customMenuId} (Version header: v3; source: v3/custom-menus-v3.json) Requires an Agency (company-level) token. OAuth scopes: custom-menu-link.write

ghl_custom_menu_get_by_idA

REQUIRES AN AGENCY-LEVEL (Company) TOKEN — spec security is Agency-Access-Only for all custom-menus ops. Get Custom Menu Link Fetches a single custom menus based on id. This endpoint allows clients to retrieve custom menu configurations, which may include menu items, categories, and associated metadata Endpoint: GET /custom-menus/{customMenuId} (Version header: v3; source: v3/custom-menus-v3.json) Requires an Agency (company-level) token. OAuth scopes: custom-menu-link.readonly

ghl_custom_menu_updateA

REQUIRES AN AGENCY-LEVEL (Company) TOKEN — spec security is Agency-Access-Only for all custom-menus ops. Update Custom Menu Link Updates an existing custom menu for a given company. Requires authentication and proper permissions. Endpoint: PUT /custom-menus/{customMenuId} (Version header: v3; source: v3/custom-menus-v3.json) Requires an Agency (company-level) token. OAuth scopes: custom-menu-link.write

ghl_custom_menu_listA

REQUIRES AN AGENCY-LEVEL (Company) TOKEN — spec security is Agency-Access-Only for all custom-menus ops. Get Custom Menu Links Fetches a collection of custom menus based on specified criteria. This endpoint allows clients to retrieve custom menu configurations, which may include menu items, categories, and associated metadata. The response can be tailored using query parameters for filtering, sorting, and pagination. Endpoint: GET /custom-menus/ (Version header: v3; source: v3/custom-menus-v3.json) Requires an Agency (company-level) token. OAuth scopes: custom-menu-link.readonly Pagination params: skip, limit — pass them to page through full result sets.

ghl_custom_menu_createA

REQUIRES AN AGENCY-LEVEL (Company) TOKEN — spec security is Agency-Access-Only for all custom-menus ops. Create Custom Menu Link Creates a new custom menu for a company. Requires authentication and proper permissions. For Icon Usage Details please refer to https://doc.clickup.com/8631005/d/h/87cpx-243696/d60fa70db6b92b2 Endpoint: POST /custom-menus/ (Version header: v3; source: v3/custom-menus-v3.json) Requires an Agency (company-level) token. OAuth scopes: custom-menu-link.write

ghl_email_verifyB

Email Verification Verify Email Endpoint: POST /email/verify (Version header: v3; source: v3/email-isv-v3.json) Requires a Sub-Account (location) token. OAuth scopes: lc-email.readonly

ghl_email_get_bulk_action_campaignA

Get Bulk Action Campaign by ID Get a single bulk action campaign by its ID Endpoint: GET /emails/locations/{locationId}/campaigns/bulk-actions/{campaignId} (Version header: v3; source: v3/emails-v3.json) Requires a Sub-Account (location) token. OAuth scopes: emails/campaigns.readonly

ghl_email_list_bulk_action_campaignsA

List Bulk Action Campaigns Get list of bulk action campaigns for a location Endpoint: GET /emails/locations/{locationId}/campaigns/bulk-actions (Version header: v3; source: v3/emails-v3.json) Requires a Sub-Account (location) token. OAuth scopes: emails/campaigns.readonly Pagination params: limit, offset — pass them to page through full result sets.

ghl_email_schedule_campaignA

Schedule Campaign Schedule or start an email campaign. The campaign must be in draft, cancelled, or paused status. Endpoint: POST /emails/locations/{locationId}/campaigns/emails/{campaignId}/schedule (Version header: v3; source: v3/emails-v3.json) Requires a Sub-Account (location) token. OAuth scopes: emails/campaigns.write

ghl_email_delete_campaignA

Delete Campaign Delete a campaign Endpoint: DELETE /emails/locations/{locationId}/campaigns/emails/{campaignId} (Version header: v3; source: v3/emails-v3.json) Requires a Sub-Account (location) token. OAuth scopes: emails/campaigns.write

ghl_email_get_campaignA

Get Email Campaign by ID Get a single email campaign by its ID Endpoint: GET /emails/locations/{locationId}/campaigns/emails/{campaignId} (Version header: v3; source: v3/emails-v3.json) Requires a Sub-Account (location) token. OAuth scopes: emails/campaigns.readonly

ghl_email_update_campaignA

Update Email Campaign Update an email campaign draft Endpoint: PATCH /emails/locations/{locationId}/campaigns/emails/{campaignId} (Version header: v3; source: v3/emails-v3.json) Requires a Sub-Account (location) token. OAuth scopes: emails/campaigns.write

ghl_email_list_campaignsA

List Email Campaigns Get list of email campaigns for a location Endpoint: GET /emails/locations/{locationId}/campaigns/emails (Version header: v3; source: v3/emails-v3.json) Requires a Sub-Account (location) token. OAuth scopes: emails/campaigns.readonly Pagination params: limit, offset — pass them to page through full result sets.

ghl_email_create_campaignA

Create Email Campaign Create a new email campaign Endpoint: POST /emails/locations/{locationId}/campaigns/emails (Version header: v3; source: v3/emails-v3.json) Requires a Sub-Account (location) token. OAuth scopes: emails/campaigns.write

ghl_email_get_campaign_statsA

Get Campaign Statistics Get statistics for email campaigns, workflows, or bulk actions Endpoint: GET /emails/locations/{locationId}/campaigns/stats/{source}/{sourceId} (Version header: v3; source: v3/emails-v3.json) Requires a Sub-Account (location) token. OAuth scopes: emails/stats.readonly

ghl_email_get_workflow_campaignA

Get Workflow Campaign by ID Get a single workflow campaign by its ID Endpoint: GET /emails/locations/{locationId}/campaigns/workflows/{campaignId} (Version header: v3; source: v3/emails-v3.json) Requires a Sub-Account (location) token. OAuth scopes: emails/campaigns.readonly

ghl_email_list_workflow_campaignsA

List Workflow Campaigns Get list of workflow campaigns for a location Endpoint: GET /emails/locations/{locationId}/campaigns/workflows (Version header: v3; source: v3/emails-v3.json) Requires a Sub-Account (location) token. OAuth scopes: emails/campaigns.readonly Pagination params: limit, offset — pass them to page through full result sets.

ghl_email_template_deleteA

Delete a template Endpoint: DELETE /emails/locations/{locationId}/templates/{templateId} (Version header: v3; source: v3/emails-v3.json) Requires a Sub-Account (location) token. OAuth scopes: emails/templates.write

ghl_email_template_getA

Get Email Template by ID Get a single email template by its ID Endpoint: GET /emails/locations/{locationId}/templates/{templateId} (Version header: v3; source: v3/emails-v3.json) Requires a Sub-Account (location) token. OAuth scopes: emails/templates.readonly

ghl_email_template_updateB

Update an email template Update email template Endpoint: PATCH /emails/locations/{locationId}/templates/{templateId} (Version header: v3; source: v3/emails-v3.json) Requires a Sub-Account (location) token. OAuth scopes: emails/templates.write

ghl_email_template_folder_createB

Create a template folder Create a new template folder Endpoint: POST /emails/locations/{locationId}/templates/folders (Version header: v3; source: v3/emails-v3.json) Requires a Sub-Account (location) token. OAuth scopes: emails/templates.write

ghl_email_template_importA

Import an email template Import a template from a provider URL Endpoint: POST /emails/locations/{locationId}/templates/import (Version header: v3; source: v3/emails-v3.json) Requires a Sub-Account (location) token. OAuth scopes: emails/templates.write

ghl_email_template_listA

List templates Get list of templates by location Endpoint: GET /emails/locations/{locationId}/templates (Version header: v3; source: v3/emails-v3.json) Requires a Sub-Account (location) token. OAuth scopes: emails/templates.readonly Pagination params: limit, offset — pass them to page through full result sets.

ghl_email_template_createB

Create an email template Create a new email template Endpoint: POST /emails/locations/{locationId}/templates (Version header: v3; source: v3/emails-v3.json) Requires a Sub-Account (location) token. OAuth scopes: emails/templates.write

ghl_file_get_by_slugA

FILES API — resolves a share-link slug to the file (sub-account token, files.readonly). Get File Get the file by slug. Endpoint: GET /files/d/{slug} (Version header: v3; source: v3/files-v3.json) OAuth scopes: files.readonly

ghl_form_listB

Get Forms Endpoint: GET /forms/ (Version header: v3; source: v3/forms-v3.json) OAuth scopes: forms.readonly Pagination params: skip, limit — pass them to page through full result sets.

ghl_form_get_submissionsB

Get Forms Submissions Endpoint: GET /forms/submissions (Version header: v3; source: v3/forms-v3.json) OAuth scopes: forms.readonly Pagination params: page, limit — pass them to page through full result sets.

ghl_form_upload_custom_filesA

EXCEPTION — no callable body schema: the official spec documents this endpoint's multipart/form-data requestBody as a bare empty object (no fields listed), so this tool's generated input schema has NO body property at all; there is currently no way to attach file bytes through this tool. Per the spec's prose, fields must be a buffer keyed <custom_field_id>_<file_id> (custom field ID + a random file id), max 50MB, one of PDF/DOCX/DOC/JPG/JPEG/PNG/GIF/CSV/XLSX/XLS/MP4/MPEG/ZIP/RAR/TXT/SVG. Fixing this requires a registry.ts change (a hand-written schema override capability that doesn't exist yet), which is out of scope for this docs-only override pass — flagged as an exception in the audit. Upload files to custom fields Post the necessary fields for the API to upload files. The files need to be a buffer with the key "< custom_field_id >_< file_id >". Here custom field id is the ID of your custom field and file id is a randomly generated id (or uuid) There is support for multiple file uploads as well. Have multiple fields in the format mentioned.File size is limited to 50 MB. The allowed file types are: PDFDOCXDOCJPGJPEGPNGGIFCSVXLSXXLSMP4MPEGZIPRARTXTSVG The API will return the updated contact object. Endpoint: POST /forms/upload-custom-files (Version header: v3; source: v3/forms-v3.json) Requires a Sub-Account (location) token. OAuth scopes: forms.write

ghl_funnel_listB

Fetch List of Funnels Retrieves a list of all funnels based on the given query parameters. Endpoint: GET /funnels/funnel/list (Version header: v3; source: v3/funnels-v3.json) Requires a Sub-Account (location) token. Pagination params: offset, limit — pass them to page through full result sets.

ghl_funnel_delete_redirect_by_idA

Delete Redirect By Id The "Delete Redirect By Id" API Allows deletion of a URL redirect from the system using its unique identifier. Use this endpoint to delete a URL redirect with the specified ID using details provided in the request payload. Endpoint: DELETE /funnels/lookup/redirect/{id} (Version header: v3; source: v3/funnels-v3.json) Requires a Sub-Account (location) token. OAuth scopes: funnels/redirect.write

ghl_funnel_update_redirect_by_idB

Update Redirect By Id The "Update Redirect By Id" API Allows updating an existing URL redirect in the system. Use this endpoint to modify a URL redirect with the specified ID using details provided in the request payload. Endpoint: PATCH /funnels/lookup/redirect/{id} (Version header: v3; source: v3/funnels-v3.json) Requires a Sub-Account (location) token. OAuth scopes: funnels/redirect.write

ghl_funnel_fetch_redirects_listA

Fetch List of Redirects Retrieves a list of all URL redirects based on the given query parameters. Endpoint: GET /funnels/lookup/redirect/list (Version header: v3; source: v3/funnels-v3.json) Requires a Sub-Account (location) token. OAuth scopes: funnels/redirect.readonly Pagination params: limit, offset — pass them to page through full result sets.

ghl_funnel_create_redirectB

Create Redirect The "Create Redirect" API Allows adding a new url redirect to the system. Use this endpoint to create a url redirect with the specified details. Ensure that the required information is provided in the request payload. Endpoint: POST /funnels/lookup/redirect (Version header: v3; source: v3/funnels-v3.json) Requires a Sub-Account (location) token. OAuth scopes: funnels/redirect.write

ghl_funnel_get_pages_count_by_idB

Fetch count of funnel pages Retrieves count of all funnel pages based on the given query parameters. Endpoint: GET /funnels/page/count (Version header: v3; source: v3/funnels-v3.json) Requires a Sub-Account (location) token.

ghl_funnel_get_pages_by_idB

Fetch list of funnel pages Retrieves a list of all funnel pages based on the given query parameters. Endpoint: GET /funnels/page (Version header: v3; source: v3/funnels-v3.json) Requires a Sub-Account (location) token. Pagination params: limit, offset — pass them to page through full result sets.

ghl_invoice_update_late_fees_configurationA

Update invoice late fees configuration API to update invoice late fees configuration by invoice id Endpoint: PATCH /invoices/{invoiceId}/late-fees-configuration (Version header: v3; source: v3/invoices-v3.json) Requires an Agency or Sub-Account token.

ghl_invoice_record_paymentA

Records a manual/offline payment against an invoice (e.g. cash, check). Does not process a live charge. Record a manual payment for an invoice API to record manual payment for an invoice by invoice id Endpoint: POST /invoices/{invoiceId}/record-payment (Version header: v3; source: v3/invoices-v3.json) Requires an Agency or Sub-Account token. OAuth scopes: invoices.write

ghl_invoice_sendB

Send invoice API to send invoice by invoice id Endpoint: POST /invoices/{invoiceId}/send (Version header: v3; source: v3/invoices-v3.json) Requires an Agency or Sub-Account token. OAuth scopes: invoices.write

ghl_invoice_voidB

Irreversible: marks the invoice as void. A voided invoice cannot be paid or reactivated afterward. Void invoice API to delete invoice by invoice id Endpoint: POST /invoices/{invoiceId}/void (Version header: v3; source: v3/invoices-v3.json) Requires an Agency or Sub-Account token. OAuth scopes: invoices.write

ghl_invoice_deleteA

Delete invoice API to delete invoice by invoice id Endpoint: DELETE /invoices/{invoiceId} (Version header: v3; source: v3/invoices-v3.json) Requires an Agency or Sub-Account token. OAuth scopes: invoices.write

ghl_invoice_getA

Get invoice API to get invoice by invoice id Endpoint: GET /invoices/{invoiceId} (Version header: v3; source: v3/invoices-v3.json) Requires an Agency or Sub-Account token. OAuth scopes: invoices.readonly

ghl_invoice_updateB

Update invoice API to update invoice by invoice id Endpoint: PUT /invoices/{invoiceId} (Version header: v3; source: v3/invoices-v3.json) Requires an Agency or Sub-Account token. OAuth scopes: invoices.write

ghl_estimate_convert_to_invoiceB

Creates a new invoice from an accepted/existing estimate. Create Invoice from Estimate Create a new invoice from an existing estimate Endpoint: POST /invoices/estimate/{estimateId}/invoice (Version header: v3; source: v3/invoices-v3.json) Requires an Agency or Sub-Account token. OAuth scopes: invoices/estimate.write

ghl_estimate_sendA

Send Estimate API to send estimate by estimate id Endpoint: POST /invoices/estimate/{estimateId}/send (Version header: v3; source: v3/invoices-v3.json) Requires an Agency or Sub-Account token. OAuth scopes: invoices/estimate.write

ghl_estimate_deleteA

Delete Estimate Delete an existing estimate Endpoint: DELETE /invoices/estimate/{estimateId} (Version header: v3; source: v3/invoices-v3.json) Requires an Agency or Sub-Account token. OAuth scopes: invoices/estimate.write

ghl_estimate_updateA

Update Estimate Update an existing estimate with new details Endpoint: PUT /invoices/estimate/{estimateId} (Version header: v3; source: v3/invoices-v3.json) Requires an Agency or Sub-Account token. OAuth scopes: invoices/estimate.write

ghl_estimate_listA

List Estimates Get a paginated list of estimates Endpoint: GET /invoices/estimate/list (Version header: v3; source: v3/invoices-v3.json) Requires an Agency or Sub-Account token. OAuth scopes: invoices/estimate.readonly Pagination params: limit, offset — pass them to page through full result sets.

ghl_estimate_generate_numberA

Generate Estimate Number Get the next estimate number for the given location Endpoint: GET /invoices/estimate/number/generate (Version header: v3; source: v3/invoices-v3.json) Requires an Agency or Sub-Account token. OAuth scopes: invoices/estimate.readonly

ghl_estimate_update_last_visited_atC

Update estimate last visited at API to update estimate last visited at by estimate id Endpoint: PATCH /invoices/estimate/stats/last-visited-at (Version header: v3; source: v3/invoices-v3.json) Requires an Agency or Sub-Account token.

ghl_estimate_template_deleteB

Delete Estimate Template Delete an existing estimate template Endpoint: DELETE /invoices/estimate/template/{templateId} (Version header: v3; source: v3/invoices-v3.json) Requires an Agency or Sub-Account token. OAuth scopes: invoices/estimate.write

ghl_estimate_template_updateA

Update Estimate Template Update an existing estimate template Endpoint: PUT /invoices/estimate/template/{templateId} (Version header: v3; source: v3/invoices-v3.json) Requires an Agency or Sub-Account token. OAuth scopes: invoices/estimate.write

ghl_estimate_template_previewA

Preview Estimate Template Get a preview of an estimate template Endpoint: GET /invoices/estimate/template/preview (Version header: v3; source: v3/invoices-v3.json) Requires an Agency or Sub-Account token. OAuth scopes: invoices/estimate.readonly

ghl_estimate_template_listA

List Estimate Templates Get a list of estimate templates or a specific template by ID Endpoint: GET /invoices/estimate/template (Version header: v3; source: v3/invoices-v3.json) Requires an Agency or Sub-Account token. OAuth scopes: invoices/estimate.readonly Pagination params: limit, offset — pass them to page through full result sets.

ghl_estimate_template_createA

Create Estimate Template Create a new estimate template Endpoint: POST /invoices/estimate/template (Version header: v3; source: v3/invoices-v3.json) Requires an Agency or Sub-Account token. OAuth scopes: invoices/estimate.write

ghl_estimate_createB

Create New Estimate Create a new estimate with the provided details Endpoint: POST /invoices/estimate (Version header: v3; source: v3/invoices-v3.json) Requires an Agency or Sub-Account token. OAuth scopes: invoices/estimate.write

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

C2.9/5.0

Scored across 855 tools

Disambiguation2/5

The descriptions are unusually diligent about flagging distinctions (e.g. 'distinct from ghl_opportunity_search', 'prefer the v3 tool'), but at 855 tools the overlap is structural: every domain carries legacy/deprecated twins (`ghl_saas_*_deprecated` vs `ghl_saas_*`, `ghl_oauth_get_installed_location` vs `..._locations`, `ghl_email_builder_template_*` vs `ghl_email_template_*`, `ghl_agent_studio_*_deprecated`), plus parallel list/search/upsert variants (`ghl_contact_list`/`lookup`/`search_advanced`/`get_duplicate`, `ghl_chat_widget_update` vs `ghl_chat_widget_patch`). An agent can tell most tools apart only by reading long prose, and misselection between near-identical legacy and current operations is highly likely.

Naming Consistency4/5

The dominant pattern `ghl_<domain>_<entity>_<action>` in snake_case is followed with impressive discipline across hundreds of tools, including deliberate renames to fix auto-generated artifacts. Minor deviations remain: `ghl_ad_fb_*` abbreviates facebook while other ad tools spell out google/linkedin, verbs mix get/fetch/list within one domain (`ghl_social_get_posts` vs `ghl_social_fetch_queues`), and `_deprecated`/`_legacy` suffixes break the pattern.

Tool Count1/5

855 tools for a single server is an extreme mismatch regardless of how broad the underlying GoHighLevel API is. Even though the surface is auto-generated from a large spec, shipping every endpoint (including deprecated and legacy variants) as a flat tool list makes navigation and selection impractical; this needs domain-level scoping or filtering.

Completeness4/5

Coverage is effectively exhaustive: contacts, calendars, conversations, invoices, courses, ads, social planner, projects, workflows, SaaS, marketplace all have full CRUD and lifecycle operations. The gaps are individual defects rather than surface holes — `ghl_form_upload_custom_files` has no body schema, and `ghl_user_update`/`ghl_user_delete` are documented as missing their `userId` path parameter.

Maintenance

ActivityMaintained
ResponsivenessNo issues