# Merrows API Documentation > Public API reference and guides for the Merrows AI employee platform: voice, chat, SMS, and email agents for ordering, post-purchase support, and customer service. - [Merrows API Documentation](/index.md) ## ai-tools The site is built to be read by agents as well as people. - [Using these docs with AI tools](/ai-tools.md): The site is built to be read by agents as well as people. ## api ### auth - [Accept an invitation](/api/auth/accept-an-invitation.md): Authenticated. The session email must match the invited address (case-insensitive). Creates the membership with the invited role; a user already holding a role accepts without gaining a second one. - [Add user to business](/api/auth/add-user-to-business.md): Add a user to the business - [Apple OAuth](/api/auth/apple-o-auth.md): Initiate Apple OAuth authentication - [Apple OAuth Callback](/api/auth/apple-o-auth-callback.md): Handle Apple OAuth callback - [Check user permission](/api/auth/check-user-permission.md): Check if user has a specific permission in a business - [Confirm MFA enrolment (step two of two)](/api/auth/confirm-mfa-enrolment-step-two-of-two.md): Enables the pending method on the authenticated user's own account once the submitted code checks out: a TOTP from the secret returned by /auth/setup-mfa, or the code it sent by email or SMS. A wrong code answers 400 MFA_CONFIRM_FAILED and changes nothing. Rate limited to 5 attempts per 15 minutes per user and 30 per hour per IP. - [Create business role](/api/auth/create-business-role.md): Create a custom role for the business - [Decode JWT](/api/auth/decode-jwt.md): Decode and verify JWT token - [Disable MFA](/api/auth/disable-mfa.md): Disable multi-factor authentication for user - [Facebook OAuth](/api/auth/facebook-o-auth.md): Initiate Facebook OAuth authentication - [Facebook OAuth Callback](/api/auth/facebook-o-auth-callback.md): Handle Facebook OAuth callback - [Get all available permissions](/api/auth/get-all-available-permissions.md): Get all permissions available in the system - [Get business](/api/auth/get-business.md): Get business details by slug - [Get business roles](/api/auth/get-business-roles.md): List all roles in a business - [Get business users](/api/auth/get-business-users.md): List all users in a business - [Get my businesses](/api/auth/get-my-businesses.md): List all businesses for authenticated user - [Get user permissions for business](/api/auth/get-user-permissions-for-business.md): Get user's permissions for a specific business - [Google OAuth](/api/auth/google-o-auth.md): Initiate Google OAuth authentication - [Google OAuth Callback](/api/auth/google-o-auth-callback.md): Handle Google OAuth callback - [Invite a member by email](/api/auth/invite-a-member-by-email.md): Create a pending invitation and email an accept link. The invitee needs no account yet; accepting requires signing in with the invited address. Requires auth.users.manage (or global admin); owner roles require an owner actor. - [List member invitations](/api/auth/list-member-invitations.md): All invitations for the tenant, newest first; pending rows past expiry carry expired=true. - [List roles](/api/auth/list-roles.md): Get all available roles - [Logout user](/api/auth/logout-user.md): Invalidate user session and token - [Merrows Auth API](/api/auth/merrows-auth-api.md): Authentication and business management API with unified MFA support - [Microsoft OAuth](/api/auth/microsoft-o-auth.md): Initiate Microsoft OAuth authentication - [Microsoft OAuth Callback](/api/auth/microsoft-o-auth-callback.md): Handle Microsoft OAuth callback - [Register new user](/api/auth/register-new-user.md): Create a new user account with email or phone number - [Remove user from business](/api/auth/remove-user-from-business.md): Remove a user from the business - [Request password reset](/api/auth/request-password-reset.md): Send password reset code to user's email or phone - [Resend a pending invitation](/api/auth/resend-a-pending-invitation.md): Rotates the token, extends the expiry, and emails a fresh accept link. The previously emailed link stops working. - [Resend verification code](/api/auth/resend-verification-code.md): Resend verification code to email or phone - [Reset password](/api/auth/reset-password.md): Reset password using verification code - [Revoke a pending invitation](/api/auth/revoke-a-pending-invitation.md): Soft-revokes a pending invitation. Owner-role invitations require an owner actor. - [Set active business](/api/auth/set-active-business.md): Set user's active business context - [Start MFA enrolment (step one of two)](/api/auth/start-mfa-enrolment-step-one-of-two.md): Begins enrolling a second factor on the authenticated user's own account (#2500). Nothing is enabled by this call. For `authenticator` a TOTP secret is stored and returned with its otpauth URI; for `email` or `sms` a code is sent to the verified contact. Call POST /auth/confirm-mfa with a code from the method to enable it. The user is taken from the JWT; a body-supplied userId is ignored. - [TikTok OAuth](/api/auth/tik-tok-o-auth.md): Initiate TikTok OAuth authentication - [TikTok OAuth Callback](/api/auth/tik-tok-o-auth-callback.md): Handle TikTok OAuth callback - [Update user role](/api/auth/update-user-role.md): Update user's role in business - [User login](/api/auth/user-login.md): Authenticate user with email/phone and password - [Verify an invitation token](/api/auth/verify-an-invitation-token.md): Public. Returns tenant, role, inviter, and invited email for a pending, unexpired token; anything else is a uniform 404. - [Verify email or phone](/api/auth/verify-email-or-phone.md): Verify user's email or phone number with code - [Verify JWT token](/api/auth/verify-jwt-token.md): Check if JWT token is valid - [Verify MFA challenge](/api/auth/verify-mfa-challenge.md): Verify multi-factor authentication codes ### edge - [Lists all active action definitions. Optionally filter by domain.](/api/edge/actions-list-actions.md): Lists all active action definitions. Optionally filter by domain. - [#514 automation-rate KPI: per-task outcomes from the #512 scoring pipeline rolled into automation / bot-failure / abandonment rates (appropriate escalations excluded from the denominator per the #509 metric contract), totalled, by UTC day, and by channel. Observational — every cell traces back to scored tasks via the tasks endpoint below.](/api/edge/analytics-get-automation-rate.md): #514 automation-rate KPI: per-task outcomes from the #512 scoring - [Drill-down for the KPI: the scored tasks behind a rate cell, filterable by outcome/channel, newest first. Each row links to the conversation transcript via conversation_id (= the analytics CallId) and carries the task's turn span.](/api/edge/analytics-get-automation-tasks.md): Drill-down for the KPI: the scored tasks behind a rate cell, filterable - [What the scored tasks in the window did, for the owner's analytics page: tasks that completed each kind of action (an order placed, a return opened, an appointment booked), and escalated tasks by how the handoff ended. Counts are tasks, in the same window and filters as automation-rate, and each one drills through automation-rate/tasks with `action` or `handoff`. A handoff that stopped at the business's own setup is reported as such, never as completed work.](/api/edge/analytics-get-automation-work.md): What the scored tasks in the window did, for the owner's analytics - [Retrieves call analytics data for a specific tenant based on a set of query parameters. This endpoint allows filtering calls by date range, flow ID, outcome, language, and translation status.](/api/edge/analytics-get-calls.md): Retrieves call analytics data for a specific tenant based on a set of query parameters. - [Merchant-facing CSAT rollup. Customer votes and AI estimates are returned as separate, scale-labelled metrics and are never averaged together or across unlike scales.](/api/edge/analytics-get-csat.md): Merchant-facing CSAT rollup. Customer votes and AI estimates are - [Create a tenant-scoped API key](/api/edge/api-keys-create-tenant-key.md): Create a tenant-scoped API key - [List API keys for a tenant](/api/edge/api-keys-list-tenant-keys.md): List API keys for a tenant - [Revoke a tenant API key](/api/edge/api-keys-revoke-tenant-key.md): Revoke a tenant API key - [Add a channel add-on (voice, SMS or the phone line) to a live subscription (#2780).](/api/edge/billing-add-addon.md): Add a channel add-on (voice, SMS or the phone line) to a live subscription (#2780). - [Move a live subscription to another plan through Stripe's subscription update API (#2780). Upgrades are prorated now; downgrades take effect next period. Never opens a second Checkout.](/api/edge/billing-change-plan.md): Move a live subscription to another plan through Stripe's subscription - [Billing_CreatePortalSession](/api/edge/billing-create-portal-session.md): Billing_CreatePortalSession - [The plans and the channel add-ons (#2780).](/api/edge/billing-get-plans.md): The plans and the channel add-ons (#2780). - [Billing_GetReloadPacks](/api/edge/billing-get-reload-packs.md): Billing_GetReloadPacks - [Billing_GetSummary](/api/edge/billing-get-summary.md): Billing_GetSummary - [Remove a channel add-on (#2780). The channel stays on until the paid period ends; the number is held for 90 days after that.](/api/edge/billing-remove-addon.md): Remove a channel add-on (#2780). The channel stays on until the paid - [Billing_StartReloadCheckout](/api/edge/billing-start-reload-checkout.md): Billing_StartReloadCheckout - [Billing_StartSubscriptionCheckout](/api/edge/billing-start-subscription-checkout.md): Billing_StartSubscriptionCheckout - [Connect Blaze to a tenant. Validates the keys against GET /partner/store and stores both encrypted; registers order webhooks best-effort when the environment has a callback base URL configured.](/api/edge/blaze-connection-connect.md): Connect Blaze to a tenant. Validates the keys against GET /partner/store - [Disconnect Blaze from a tenant.](/api/edge/blaze-connection-disconnect.md): Disconnect Blaze from a tenant. - [Get the current Blaze connection for a tenant.](/api/edge/blaze-connection-get-connection.md): Get the current Blaze connection for a tenant. - [Test the Blaze connection by calling GET /partner/store with the stored keys.](/api/edge/blaze-connection-test-connection.md): Test the Blaze connection by calling GET /partner/store with the stored keys. - [Connect a booking provider. Encrypts + stores credentials and sets the active provider.](/api/edge/booking-connection-connect.md): Connect a booking provider. Encrypts + stores credentials and sets the active provider. - [Disconnect the tenant's booking provider and clear the active provider.](/api/edge/booking-connection-disconnect.md): Disconnect the tenant's booking provider and clear the active provider. - [Get the tenant's current booking connection (200 with null body if unconfigured).](/api/edge/booking-connection-get-connection.md): Get the tenant's current booking connection (200 with null body if unconfigured). - [Capabilities_Delete](/api/edge/capabilities-delete.md): Capabilities_Delete - [Capabilities_Get](/api/edge/capabilities-get.md): Capabilities_Get - [Capabilities_List](/api/edge/capabilities-list.md): Capabilities_List - [Capabilities_Update](/api/edge/capabilities-update.md): Capabilities_Update - [Retrieves the conversation settings for a specific tenant. This includes settings like dead-air thresholds, TTS chunk thresholds, and global DTMF overrides.](/api/edge/conversation-settings-get.md): Retrieves the conversation settings for a specific tenant. - [Retrieves the menu item clarification settings for a specific tenant. Controls how the bot handles variations, modifiers, and ambiguous item matches.](/api/edge/conversation-settings-get-clarification-settings.md): Retrieves the menu item clarification settings for a specific tenant. - [Creates or updates the conversation settings for a specific tenant. This allows for fine-tuning conversation behavior and DTMF handling.](/api/edge/conversation-settings-update.md): Creates or updates the conversation settings for a specific tenant. - [Updates the menu item clarification settings for a specific tenant. Only provided fields will be updated; others retain their current values.](/api/edge/conversation-settings-update-clarification-settings.md): Updates the menu item clarification settings for a specific tenant. - [Retrieves the session summary for a specific call. The session summary contains metadata about the conversation, such as the start and end times, duration, and outcome.](/api/edge/conversation-transcripts-get-session.md): Retrieves the session summary for a specific call. - [Retrieves the transcript for a specific call. The transcript can be filtered by speaker and turn number, and returned in either a compact or verbose format.](/api/edge/conversation-transcripts-get-transcript.md): Retrieves the transcript for a specific call. - [Removes conversation-level TTS settings, reverting to the tenant default.](/api/edge/conversation-tts-settings-delete.md): Removes conversation-level TTS settings, reverting to the tenant default. - [Gets the TTS settings for a conversation, optionally pinned to a version. Returns the version-specific row if it exists, otherwise the version-agnostic row.](/api/edge/conversation-tts-settings-get.md): Gets the TTS settings for a conversation, optionally pinned to a version. - [Creates or updates TTS settings for a conversation. Only provided (non-null) fields are written; omitted fields retain their current value on update.](/api/edge/conversation-tts-settings-upsert.md): Creates or updates TTS settings for a conversation. - [Create a new draft conversation.](/api/edge/conversations-create-draft.md): Create a new draft conversation. - [Delete a never-published draft conversation (#354). Published conversations return 409; create-and-abandon drafts are the only hard-deletable state.](/api/edge/conversations-delete-draft.md): Delete a never-published draft conversation (#354). Published conversations - [Compute a structural diff between two versions of a conversation.](/api/edge/conversations-diff-versions.md): Compute a structural diff between two versions of a conversation. - [Get a specific conversation by slug or ID (returns latest version).](/api/edge/conversations-get.md): Get a specific conversation by slug or ID (returns latest version). - [List all conversations for a tenant.](/api/edge/conversations-list.md): List all conversations for a tenant. - [List all versions for a conversation slug.](/api/edge/conversations-list-versions.md): List all versions for a conversation slug. - [Publish a draft conversation, creating a new immutable version.](/api/edge/conversations-publish.md): Publish a draft conversation, creating a new immutable version. - [Rollback a conversation to a specific version, creating a new version with the target's definition.](/api/edge/conversations-rollback.md): Rollback a conversation to a specific version, creating a new version with the target's definition. - [Update an existing draft conversation.](/api/edge/conversations-update-draft.md): Update an existing draft conversation. - [EmailConversations_Close](/api/edge/email-conversations-close.md): EmailConversations_Close - [Escalate an email conversation to the helpdesk provider. Builds transcript from the full message thread and creates a helpdesk ticket.](/api/edge/email-conversations-escalate.md): Escalate an email conversation to the helpdesk provider. - [EmailConversations_Get](/api/edge/email-conversations-get.md): EmailConversations_Get - [EmailConversations_List](/api/edge/email-conversations-list.md): EmailConversations_List - [EmailConversations_Reply](/api/edge/email-conversations-reply.md): EmailConversations_Reply - [Get a single delivery log entry.](/api/edge/email-delivery-get.md): Get a single delivery log entry. - [List email delivery logs with optional filters.](/api/edge/email-delivery-list.md): List email delivery logs with optional filters. - [Get aggregate delivery stats for a tenant.](/api/edge/email-delivery-stats.md): Get aggregate delivery stats for a tenant. - [Get current email settings for a tenant](/api/edge/email-settings-get.md): Get current email settings for a tenant - [Get provider-specific email forwarding setup guide](/api/edge/email-settings-get-setup-guide.md): Get provider-specific email forwarding setup guide - [Get forwarding verification status for a tenant](/api/edge/email-settings-get-verification-status.md): Get forwarding verification status for a tenant - [List recent inbound emails for a tenant](/api/edge/email-settings-list-inbound-emails.md): List recent inbound emails for a tenant - [Start email forwarding verification — sends a verification email to the external address. When that address is forwarded to the tenant's inbound address the webhook auto-detects the token and marks the verification complete.](/api/edge/email-settings-start-forwarding-verification.md): Start email forwarding verification — sends a verification email to the - [Update email settings for a tenant. The inbound routing address is NOT writable here (#1361): it is the identity the webhook matches inbound mail against, and the old single-column design let the editable reply-from field silently overwrite it. Custom inbound addresses are an operator concern; reply-from is the merchant-facing setting.](/api/edge/email-settings-update.md): Update email settings for a tenant. The inbound routing address is NOT - [EmailTemplates_Create](/api/edge/email-templates-create.md): EmailTemplates_Create - [EmailTemplates_Delete](/api/edge/email-templates-delete.md): EmailTemplates_Delete - [EmailTemplates_Get](/api/edge/email-templates-get.md): EmailTemplates_Get - [EmailTemplates_List](/api/edge/email-templates-list.md): EmailTemplates_List - [Render a template with sample variables and return the branded HTML preview.](/api/edge/email-templates-preview.md): Render a template with sample variables and return the branded HTML preview. - [Send a test email using this template.](/api/edge/email-templates-send-test.md): Send a test email using this template. - [EmailTemplates_Update](/api/edge/email-templates-update.md): EmailTemplates_Update - [EmbedConnection_CreateOrRotateKey](/api/edge/embed-connection-create-or-rotate-key.md): EmbedConnection_CreateOrRotateKey - [EmbedConnection_Get](/api/edge/embed-connection-get.md): EmbedConnection_Get - [Embed usage rollup (#830): sessions/messages/top-origins from the Mongo analytics documents stamped Source = 'website_embed'. Message counts cover persisted (ended) sessions only; live sessions appear in the session count with 0 messages until their transcript persists.](/api/edge/embed-connection-get-analytics.md): Embed usage rollup (#830): sessions/messages/top-origins from the - [EmbedConnection_Update](/api/edge/embed-connection-update.md): EmbedConnection_Update - [Add a variant to an experiment.](/api/edge/experiments-add-variant.md): Add a variant to an experiment. - [Conclude an experiment with an optional winning variant. If promoteWinner is true, updates the TenantConversationAssignment.](/api/edge/experiments-conclude.md): Conclude an experiment with an optional winning variant. - [Create a new experiment in draft status.](/api/edge/experiments-create.md): Create a new experiment in draft status. - [Delete a draft experiment.](/api/edge/experiments-delete.md): Delete a draft experiment. - [Remove a variant.](/api/edge/experiments-delete-variant.md): Remove a variant. - [Get experiment details including variants and assignment counts.](/api/edge/experiments-get.md): Get experiment details including variants and assignment counts. - [List all experiments for a tenant, including variant counts.](/api/edge/experiments-list.md): List all experiments for a tenant, including variant counts. - [Pause a running experiment.](/api/edge/experiments-pause.md): Pause a running experiment. - [Get assignment counts per variant for an experiment.](/api/edge/experiments-results.md): Get assignment counts per variant for an experiment. - [Resume a paused experiment.](/api/edge/experiments-resume.md): Resume a paused experiment. - [Start an experiment. Validates: weights sum to 100, >= 2 variants, no other running experiment for tenant.](/api/edge/experiments-start.md): Start an experiment. Validates: weights sum to 100, >= 2 variants, no other running experiment for tenant. - [Update a draft experiment. Returns 409 if not in draft status.](/api/edge/experiments-update.md): Update a draft experiment. Returns 409 if not in draft status. - [Update a variant.](/api/edge/experiments-update-variant.md): Update a variant. - [Connect Gladly to a tenant. Encrypts and stores credentials. Optionally registers webhook with Gladly.](/api/edge/gladly-connection-connect.md): Connect Gladly to a tenant. Encrypts and stores credentials. - [Disconnect Gladly from a tenant.](/api/edge/gladly-connection-disconnect.md): Disconnect Gladly from a tenant. - [Get the current Gladly connection for a tenant.](/api/edge/gladly-connection-get-connection.md): Get the current Gladly connection for a tenant. - [Test the Gladly connection by calling the agents endpoint.](/api/edge/gladly-connection-test-connection.md): Test the Gladly connection by calling the agents endpoint. - [Connect Gorgias to a tenant. Encrypts and stores credentials.](/api/edge/gorgias-connection-connect.md): Connect Gorgias to a tenant. Encrypts and stores credentials. - [Disconnect Gorgias from a tenant.](/api/edge/gorgias-connection-disconnect.md): Disconnect Gorgias from a tenant. - [Get the current Gorgias connection for a tenant.](/api/edge/gorgias-connection-get-connection.md): Get the current Gorgias connection for a tenant. - [Test the Gorgias connection by calling the account endpoint.](/api/edge/gorgias-connection-test-connection.md): Test the Gorgias connection by calling the account endpoint. - [Add a note to an existing helpdesk conversation.](/api/edge/helpdesk-add-note.md): Add a note to an existing helpdesk conversation. - [Create a report export job.](/api/edge/helpdesk-create-report.md): Create a report export job. - [Manually escalate to helpdesk from the portal.](/api/edge/helpdesk-escalate.md): Manually escalate to helpdesk from the portal. - [Get a single conversation link by ID.](/api/edge/helpdesk-get-conversation.md): Get a single conversation link by ID. - [Check status of a report job.](/api/edge/helpdesk-get-report-status.md): Check status of a report job. - [List agents from the helpdesk provider.](/api/edge/helpdesk-list-agents.md): List agents from the helpdesk provider. - [List conversation links (escalation history) for the tenant.](/api/edge/helpdesk-list-conversations.md): List conversation links (escalation history) for the tenant. - [List inboxes from the helpdesk provider.](/api/edge/helpdesk-list-inboxes.md): List inboxes from the helpdesk provider. - [IntegrationCapabilities_Get](/api/edge/integration-capabilities-get.md): IntegrationCapabilities_Get - [Removes a per-tenant override for a system intent, resetting it to system defaults.](/api/edge/intent-catalog-delete-override.md): Removes a per-tenant override for a system intent, resetting it to system defaults. - [Returns the full system intent catalog for this tenant's type, including override metadata (enabled/disabled, custom description/examples).](/api/edge/intent-catalog-get-catalog.md): Returns the full system intent catalog for this tenant's type, - [Creates or updates a per-tenant override for a system intent. Use this to enable/disable intents or customize their description/examples.](/api/edge/intent-catalog-upsert-override.md): Creates or updates a per-tenant override for a system intent. - [Connect Kustomer to a tenant. Encrypts and stores the API token.](/api/edge/kustomer-connection-connect.md): Connect Kustomer to a tenant. Encrypts and stores the API token. - [Disconnect Kustomer from a tenant.](/api/edge/kustomer-connection-disconnect.md): Disconnect Kustomer from a tenant. - [Get the current Kustomer connection for a tenant.](/api/edge/kustomer-connection-get-connection.md): Get the current Kustomer connection for a tenant. - [Test the Kustomer connection by calling the current user endpoint.](/api/edge/kustomer-connection-test-connection.md): Test the Kustomer connection by calling the current user endpoint. - [LlmPrompts_Delete](/api/edge/llm-prompts-delete.md): LlmPrompts_Delete - [LlmPrompts_Get](/api/edge/llm-prompts-get.md): LlmPrompts_Get - [LlmPrompts_List](/api/edge/llm-prompts-list.md): LlmPrompts_List - [LlmPrompts_Update](/api/edge/llm-prompts-update.md): LlmPrompts_Update - [Connect Meadow to a tenant. Validates the keys and stores them encrypted.](/api/edge/meadow-connection-connect.md): Connect Meadow to a tenant. Validates the keys and stores them encrypted. - [Disconnect Meadow from a tenant.](/api/edge/meadow-connection-disconnect.md): Disconnect Meadow from a tenant. - [Get the current Meadow connection for a tenant.](/api/edge/meadow-connection-get-connection.md): Get the current Meadow connection for a tenant. - [Test the Meadow connection by calling the organization endpoint.](/api/edge/meadow-connection-test-connection.md): Test the Meadow connection by calling the organization endpoint. - [Merrows Edge API](/api/edge/merrows-edge-api.md): Public API for building on the Merrows platform: conversations, analytics, transcripts, experiments, telephony, email/SMS templates, and integration management. - [Preview return financials before creating. Returns 409 if tenant uses Redo as returns provider.](/api/edge/oms-calculate-return.md): Preview return financials before creating. - [Cancel an order (irreversible)](/api/edge/oms-cancel-order.md): Cancel an order (irreversible) - [Cancel a subscription](/api/edge/oms-cancel-subscription.md): Cancel a subscription - [Create an exchange (return items + ship new items). Returns 409 if tenant uses Redo as returns provider.](/api/edge/oms-create-exchange.md): Create an exchange (return items + ship new items). - [Create a return request for an order. Returns 409 if tenant uses Redo as returns provider.](/api/edge/oms-create-return.md): Create a return request for an order. - [Get order details with fulfillments and tracking info](/api/edge/oms-get-order.md): Get order details with fulfillments and tracking info - [Get subscription details](/api/edge/oms-get-subscription.md): Get subscription details - [List subscriptions for a customer](/api/edge/oms-list-subscriptions.md): List subscriptions for a customer - [Pause a subscription](/api/edge/oms-pause-subscription.md): Pause a subscription - [Process/confirm a return (disposition + refund). Returns 409 if tenant uses Redo as returns provider.](/api/edge/oms-process-return.md): Process/confirm a return (disposition + refund). - [Resume a paused subscription](/api/edge/oms-resume-subscription.md): Resume a paused subscription - [Search orders by email, phone, name, or status](/api/edge/oms-search-orders.md): Search orders by email, phone, name, or status - [Skip the next shipment/charge on a subscription (#1507). Returns 501 when the resolved provider has no skip support (OMS bridge).](/api/edge/oms-skip-next-shipment.md): Skip the next shipment/charge on a subscription (#1507). - [Swap the product variant on a subscription (#1507). Returns 501 when the resolved provider has no swap support (OMS bridge).](/api/edge/oms-swap-subscription-variant.md): Swap the product variant on a subscription (#1507). - [Restore a previously skipped shipment/charge on a subscription (#1507). Returns 501 when the resolved provider has no skip support (OMS bridge).](/api/edge/oms-unskip-shipment.md): Restore a previously skipped shipment/charge on a subscription (#1507). - [OutboundCalls_GetStatus](/api/edge/outbound-calls-get-status.md): OutboundCalls_GetStatus - [OutboundCalls_Hangup](/api/edge/outbound-calls-hangup.md): OutboundCalls_Hangup - [OutboundCalls_InitiateCall](/api/edge/outbound-calls-initiate-call.md): OutboundCalls_InitiateCall - [Creates an order with a list of items and sends a payment link to the customer via SMS.](/api/edge/payment-create-order-with-payment-link.md): Creates an order with a list of items and sends a payment link to the customer via SMS. - [Creates a quick payment link for a simple amount and sends it to the customer via SMS.](/api/edge/payment-create-quick-payment-link.md): Creates a quick payment link for a simple amount and sends it to the customer via SMS. - [Retrieves the status of a specific payment link.](/api/edge/payment-get-payment-link-status.md): Retrieves the status of a specific payment link. - [An example endpoint demonstrating how a voice order can be processed and converted into a payment link.](/api/edge/payment-process-voice-order.md): An example endpoint demonstrating how a voice order can be processed and converted into a payment link. - [Creates a new order in the Point of Sale (POS) system for a specific tenant.](/api/edge/pos-create-order.md): Creates a new order in the Point of Sale (POS) system for a specific tenant. - [Retrieves the menu for a specific tenant and location from the configured Point of Sale (POS) system.](/api/edge/pos-get-menu.md): Retrieves the menu for a specific tenant and location from the configured Point of Sale (POS) system. - [Retrieves a specific order from the Point of Sale (POS) system.](/api/edge/pos-get-order.md): Retrieves a specific order from the Point of Sale (POS) system. - [Connect POSaBIT to a tenant. Validates the venue credentials and stores encrypted.](/api/edge/posabit-connection-connect.md): Connect POSaBIT to a tenant. Validates the venue credentials and stores encrypted. - [Disconnect POSaBIT from a tenant.](/api/edge/posabit-connection-disconnect.md): Disconnect POSaBIT from a tenant. - [Get the current POSaBIT connection for a tenant.](/api/edge/posabit-connection-get-connection.md): Get the current POSaBIT connection for a tenant. - [Test the POSaBIT connection by calling the venue info endpoint.](/api/edge/posabit-connection-test-connection.md): Test the POSaBIT connection by calling the venue info endpoint. - [Connect Recharge to a tenant. Verifies the token against the live API first, then encrypts and stores it.](/api/edge/recharge-connection-connect.md): Connect Recharge to a tenant. Verifies the token against the live API - [Disconnect Recharge from a tenant (soft: the row survives for revive).](/api/edge/recharge-connection-disconnect.md): Disconnect Recharge from a tenant (soft: the row survives for revive). - [Get the current Recharge connection for a tenant.](/api/edge/recharge-connection-get-connection.md): Get the current Recharge connection for a tenant. - [Test the stored Recharge connection with an authenticated store read.](/api/edge/recharge-connection-test-connection.md): Test the stored Recharge connection with an authenticated store read. - [Update the display-only settings on the active connection.](/api/edge/recharge-connection-update-settings.md): Update the display-only settings on the active connection. - [Connect Redo to a tenant. Encrypts and stores API token, store ID, and webhook secret. Optionally registers webhook with Redo API.](/api/edge/redo-connection-connect.md): Connect Redo to a tenant. Encrypts and stores API token, store ID, and webhook secret. - [Disconnect Redo from a tenant](/api/edge/redo-connection-disconnect.md): Disconnect Redo from a tenant - [Get the current Redo connection for a tenant](/api/edge/redo-connection-get-connection.md): Get the current Redo connection for a tenant - [Get the customer return portal URL for this tenant.](/api/edge/returns-get-portal-link.md): Get the customer return portal URL for this tenant. - [Get a single return case by its external return ID, with event history.](/api/edge/returns-get-return-case.md): Get a single return case by its external return ID, with event history. - [List return cases for a tenant, with optional filters.](/api/edge/returns-list-return-cases.md): List return cases for a tenant, with optional filters. - [Update the status of a return via the returns provider, then update local mirror. Valid target statuses: complete, open, flagged, rejected, deleted.](/api/edge/returns-update-return-status.md): Update the status of a return via the returns provider, then update local mirror. - [Attach an install the merchant approved on Shopify to this tenant. The install ran OAuth before the merchant signed in (App Store requirement 2.3.2), so the callback could not know the workspace and parked the grant under a claim token. The token is single use and expires after Edge.API.Shopify.ShopifyOAuthStart.ClaimTtl. A claim that is refused for a reason the merchant can fix (the workspace already holds another store, or another business holds this one) is put back for the rest of its lifetime, so the merchant can fix it and retry without installing again.](/api/edge/shopify-connection-claim.md): Attach an install the merchant approved on Shopify to this tenant. - [Connect a Shopify store to a tenant using OAuth 2.0 client credentials. Exchanges client ID + secret for an access token, validates via GraphQL shop query, stores encrypted credentials, and registers webhooks.](/api/edge/shopify-connection-connect.md): Connect a Shopify store to a tenant using OAuth 2.0 client credentials. - [Disconnect a Shopify store from a tenant](/api/edge/shopify-connection-disconnect.md): Disconnect a Shopify store from a tenant - [Get the current Shopify connection for a tenant](/api/edge/shopify-connection-get-connection.md): Get the current Shopify connection for a tenant - [The consent URL for the store this tenant already holds, for a reconnect after Shopify stopped accepting its token. Only the stored shop is ever used: the tenant cannot name another store here, and the caller must be allowed to manage this tenant's integrations. This replaces the anonymous /api/shopify/oauth/authorize, which took any tenant slug and any shop from anyone.](/api/edge/shopify-connection-reauthorize.md): The consent URL for the store this tenant already holds, for a - [Current inbound texting settings for a tenant.](/api/edge/sms-settings-get.md): Current inbound texting settings for a tenant. - [Update inbound texting settings for a tenant. A field you omit keeps its stored value; an empty conversation slug clears it.](/api/edge/sms-settings-update.md): Update inbound texting settings for a tenant. A field you omit keeps - [SmsTemplates_Create](/api/edge/sms-templates-create.md): SmsTemplates_Create - [SmsTemplates_Delete](/api/edge/sms-templates-delete.md): SmsTemplates_Delete - [SmsTemplates_Get](/api/edge/sms-templates-get.md): SmsTemplates_Get - [SmsTemplates_List](/api/edge/sms-templates-list.md): SmsTemplates_List - [Render a template with sample variables.](/api/edge/sms-templates-preview.md): Render a template with sample variables. - [SmsTemplates_Update](/api/edge/sms-templates-update.md): SmsTemplates_Update - [List connections visible to this tenant: its own linked connection plus unclaimed connections available for linking. Response item shape matches the admin listing so the portal component is URL-swap compatible.](/api/edge/square-connection-get-connections.md): List connections visible to this tenant: its own linked connection plus - [Get locations for a merchant connection this tenant may see.](/api/edge/square-connection-get-locations.md): Get locations for a merchant connection this tenant may see. - [Link an unclaimed Square connection to this tenant.](/api/edge/square-connection-link.md): Link an unclaimed Square connection to this tenant. - [Unlink this tenant's Square connection.](/api/edge/square-connection-unlink.md): Unlink this tenant's Square connection. - [TenantBlueprints_ApplyGenerationRun](/api/edge/tenant-blueprints-apply-generation-run.md): TenantBlueprints_ApplyGenerationRun - [Delete a never-published draft blueprint (#354). Published blueprints return 409.](/api/edge/tenant-blueprints-delete-draft.md): Delete a never-published draft blueprint (#354). Published blueprints return 409. - [TenantBlueprints_GenerateRecipe](/api/edge/tenant-blueprints-generate-recipe.md): TenantBlueprints_GenerateRecipe - [TenantBlueprints_Get](/api/edge/tenant-blueprints-get.md): TenantBlueprints_Get - [TenantBlueprints_GetGenerationRun](/api/edge/tenant-blueprints-get-generation-run.md): TenantBlueprints_GetGenerationRun - [TenantBlueprints_List](/api/edge/tenant-blueprints-list.md): TenantBlueprints_List - [TenantBlueprints_ListGenerationRuns](/api/edge/tenant-blueprints-list-generation-runs.md): TenantBlueprints_ListGenerationRuns - [TenantBlueprints_PreviewCompose](/api/edge/tenant-blueprints-preview-compose.md): TenantBlueprints_PreviewCompose - [TenantBlueprints_Publish](/api/edge/tenant-blueprints-publish.md): TenantBlueprints_Publish - [TenantBlueprints_Update](/api/edge/tenant-blueprints-update.md): TenantBlueprints_Update - [TenantBlueprints_Versions](/api/edge/tenant-blueprints-versions.md): TenantBlueprints_Versions - [P2-A: what changed between two of the tenant's versions of this skill, field by field with the old and new values. `to` is a version number or `draft`.](/api/edge/tenant-capability-flows-diff-versions.md): P2-A: what changed between two of the tenant's versions of this skill, - [#1046 Phase 2: constrained node-graph generation. Writes nothing to CapabilityFlows — a success returns the proposal for the editor to load as unsaved dirty state; a failed run returns 422 with the last attempt and its violations. Publish (with its hard gate) remains the only door to going live.](/api/edge/tenant-capability-flows-generate.md): #1046 Phase 2: constrained node-graph generation. Writes nothing to - [TenantCapabilityFlows_Get](/api/edge/tenant-capability-flows-get.md): TenantCapabilityFlows_Get - [TenantCapabilityFlows_List](/api/edge/tenant-capability-flows-list.md): TenantCapabilityFlows_List - [#1046 Phase 2: the composed node universe of the tenant blueprint referencing this capability. The server-side twin of the portal's composedNodeIds util, which reconstructs from summaries and misses non-entry nodes in sibling capabilities.](/api/edge/tenant-capability-flows-node-scope.md): #1046 Phase 2: the composed node universe of the tenant blueprint - [TenantCapabilityFlows_Publish](/api/edge/tenant-capability-flows-publish.md): TenantCapabilityFlows_Publish - [#2433: forget the tenant's own copy of this skill so customers hear the standard version again. Deletes every tenant-scoped row for the capability, published history included, then recomposes. P2-A: the rows are copied to CapabilityFlowSnapshots first, so History can restore them.](/api/edge/tenant-capability-flows-reset.md): #2433: forget the tenant's own copy of this skill so customers hear the - [P2-A: restore a set-aside copy as a draft. Never publishes.](/api/edge/tenant-capability-flows-restore-snapshot.md): P2-A: restore a set-aside copy as a draft. Never publishes. - [P2-A: copy a published version into the draft. Never publishes; the merchant publishes the restored draft like any other edit.](/api/edge/tenant-capability-flows-restore-version.md): P2-A: copy a published version into the draft. Never publishes; the - [P2-A: the copies Reset set aside, newest first.](/api/edge/tenant-capability-flows-snapshots.md): P2-A: the copies Reset set aside, newest first. - [TenantCapabilityFlows_Update](/api/edge/tenant-capability-flows-update.md): TenantCapabilityFlows_Update - [#2433: merge the template's changes since this fork's base version into the tenant draft. Conflicts keep the merchant's value and are named.](/api/edge/tenant-capability-flows-update-from-template.md): #2433: merge the template's changes since this fork's base version into - [TenantCapabilityFlows_Versions](/api/edge/tenant-capability-flows-versions.md): TenantCapabilityFlows_Versions - [Register a new custom email domain with Resend. Returns DNS records to configure.](/api/edge/tenant-domains-add.md): Register a new custom email domain with Resend. Returns DNS records to configure. - [Get a domain's details including DNS records the tenant needs to configure.](/api/edge/tenant-domains-get.md): Get a domain's details including DNS records the tenant needs to configure. - [List all custom email domains for this tenant.](/api/edge/tenant-domains-list.md): List all custom email domains for this tenant. - [Remove a custom domain.](/api/edge/tenant-domains-remove.md): Remove a custom domain. - [Trigger domain verification after DNS records have been configured.](/api/edge/tenant-domains-verify.md): Trigger domain verification after DNS records have been configured. - [TenantFaqCrawl_AddConsent](/api/edge/tenant-faq-crawl-add-consent.md): TenantFaqCrawl_AddConsent - [Approve, reject, reopen or delete a selection in one call. The review queue is a bulk-select table, so doing this row by row would fire one request, one cache eviction and one corpus refresh per row.](/api/edge/tenant-faq-crawl-bulk-update-entries.md): Approve, reject, reopen or delete a selection in one call. The review - [Queue a crawl and return immediately. This used to run the whole pipeline inline, which meant the merchant stared at a disabled button for minutes and lost every result if the six-minute HttpClient timeout fired. FaqCrawlWorkerService picks the run up; the portal polls GET runs/{id} for the progress bar.](/api/edge/tenant-faq-crawl-crawl-now.md): Queue a crawl and return immediately. This used to run the whole - [Add one FAQ by hand. It lands approved by default: the merchant wrote it, so there is nothing to review. No consent is attached, which is what migration 406 made possible.](/api/edge/tenant-faq-crawl-create-entry.md): Add one FAQ by hand. It lands approved by default: the merchant wrote - [TenantFaqCrawl_DeleteEntry](/api/edge/tenant-faq-crawl-delete-entry.md): TenantFaqCrawl_DeleteEntry - [TenantFaqCrawl_GetConsent](/api/edge/tenant-faq-crawl-get-consent.md): TenantFaqCrawl_GetConsent - [TenantFaqCrawl_GetRun](/api/edge/tenant-faq-crawl-get-run.md): TenantFaqCrawl_GetRun - [Import a CSV or JSON export. Partial success is the normal outcome and is reported row by row: a file with one bad line should not cost the merchant the other two hundred.](/api/edge/tenant-faq-crawl-import-entries.md): Import a CSV or JSON export. Partial success is the normal outcome and - [TenantFaqCrawl_ListConsents](/api/edge/tenant-faq-crawl-list-consents.md): TenantFaqCrawl_ListConsents - [The review queue. Paged and searchable because a crawl of a real help centre returns hundreds of rows, and scoped by consent because a tenant with two registered domains was previously shown the same tenant-wide list under both.](/api/edge/tenant-faq-crawl-list-entries.md): The review queue. Paged and searchable because a crawl of a real help - [TenantFaqCrawl_ListRuns](/api/edge/tenant-faq-crawl-list-runs.md): TenantFaqCrawl_ListRuns - [TenantFaqCrawl_RevokeConsent](/api/edge/tenant-faq-crawl-revoke-consent.md): TenantFaqCrawl_RevokeConsent - [TenantFaqCrawl_UpdateEntry](/api/edge/tenant-faq-crawl-update-entry.md): TenantFaqCrawl_UpdateEntry - [TenantLiveStatus_Get](/api/edge/tenant-live-status-get.md): TenantLiveStatus_Get - [Submit a phone number provisioning request for this tenant. Idempotent on the `Idempotency-Key` header: a replay of the same key in this environment returns the original row and does not notify again. Missing header is accepted; Edge mints a key the way the demo workspace request path does. Unique index `ux_PhoneNumberRequests_IdempotencyKey_Env` is the race backstop.](/api/edge/tenant-phone-create-request.md): Submit a phone number provisioning request for this tenant. - [Get the most recent pending or provisioning phone number request for this tenant.](/api/edge/tenant-phone-get-current-request.md): Get the most recent pending or provisioning phone number request for this tenant. - [Get paginated SMS message log for this tenant.](/api/edge/tenant-phone-get-messages.md): Get paginated SMS message log for this tenant. - [Get the current phone number status for this tenant. Returns the assigned Twilio number with provisioning indicators.](/api/edge/tenant-phone-get-phone-number-status.md): Get the current phone number status for this tenant. - [Get SMS statistics for the tenant's phone number over the last N days.](/api/edge/tenant-phone-get-sms-stats.md): Get SMS statistics for the tenant's phone number over the last N days. - [TenantPolicyRules_GetHandoff](/api/edge/tenant-policy-rules-get-handoff.md): TenantPolicyRules_GetHandoff - [TenantPolicyRules_GetTone](/api/edge/tenant-policy-rules-get-tone.md): TenantPolicyRules_GetTone - [TenantPolicyRules_GetVerification](/api/edge/tenant-policy-rules-get-verification.md): TenantPolicyRules_GetVerification - [TenantPolicyRules_PutHandoff](/api/edge/tenant-policy-rules-put-handoff.md): TenantPolicyRules_PutHandoff - [TenantPolicyRules_PutTone](/api/edge/tenant-policy-rules-put-tone.md): TenantPolicyRules_PutTone - [TenantPolicyRules_PutVerification](/api/edge/tenant-policy-rules-put-verification.md): TenantPolicyRules_PutVerification - [TenantShortLinkDomains_Add](/api/edge/tenant-short-link-domains-add.md): TenantShortLinkDomains_Add - [TenantShortLinkDomains_Get](/api/edge/tenant-short-link-domains-get.md): TenantShortLinkDomains_Get - [TenantShortLinkDomains_List](/api/edge/tenant-short-link-domains-list.md): TenantShortLinkDomains_List - [TenantShortLinkDomains_Remove](/api/edge/tenant-short-link-domains-remove.md): TenantShortLinkDomains_Remove - [TenantShortLinkDomains_Verify](/api/edge/tenant-short-link-domains-verify.md): TenantShortLinkDomains_Verify - [TenantSkillChecks_Create](/api/edge/tenant-skill-checks-create.md): TenantSkillChecks_Create - [TenantSkillChecks_Delete](/api/edge/tenant-skill-checks-delete.md): TenantSkillChecks_Delete - [TenantSkillChecks_GetRun](/api/edge/tenant-skill-checks-get-run.md): TenantSkillChecks_GetRun - [TenantSkillChecks_List](/api/edge/tenant-skill-checks-list.md): TenantSkillChecks_List - [TenantSkillChecks_SetActive](/api/edge/tenant-skill-checks-set-active.md): TenantSkillChecks_SetActive - [Queues a run of every active check against the saved draft. 202 with the run; an unfinished run is returned instead of a second one.](/api/edge/tenant-skill-checks-start-run.md): Queues a run of every active check against the saved draft. - [TenantSkillChecks_Update](/api/edge/tenant-skill-checks-update.md): TenantSkillChecks_Update - [TenantWelcomeAudio_Delete](/api/edge/tenant-welcome-audio-delete.md): TenantWelcomeAudio_Delete - [TenantWelcomeAudio_List](/api/edge/tenant-welcome-audio-list.md): TenantWelcomeAudio_List - [TenantWelcomeAudio_Upload](/api/edge/tenant-welcome-audio-upload.md): TenantWelcomeAudio_Upload - [Whether this tenant's hard cases can reach a person (#1823, #1932). Read by the go-live checklist so a merchant finds out from us rather than from a customer who asked for a human and was told to go and find one. The same service answers the blueprint publish gate and the live-status card, so the explanation, the enforcement and the standing dashboard answer cannot drift apart. The payload carries the sentence and the page that fixes it; the portal renders, it does not decide.](/api/edge/tenants-get-escalation-target.md): Whether this tenant's hard cases can reach a person (#1823, #1932). - [Retrieves a specific tenant by its business slug.](/api/edge/tenants-get-tenant.md): Retrieves a specific tenant by its business slug. - [Returns the current backfill status for every language the tenant has recently triggered a backfill for. Empty list when no backfill has run in the last 24 hours.](/api/edge/tenants-get-translation-backfill-status.md): Returns the current backfill status for every language the tenant has - [Updates only the tenant's language list, so the conversation editor can register a language the moment an author adds one to a node (#1030). Exactly one entry must be primary. Newly added non-primary languages trigger a translation backfill across the tenant's conversations; progress is available from the translation-backfill-status endpoint.](/api/edge/tenants-update-tenant-languages.md): Updates only the tenant's language list, so the conversation editor can - [Updates the business-profile fields of your own tenant: display name, contact email, assistant name, business hours, escalation policy, phone and forwarding numbers, callback behaviour, and the email idle timeout. Requires the tenants.settings.manage permission.](/api/edge/tenants-update-tenant-profile.md): PATCH semantics: a field you omit keeps its stored value. - [Tenants_UpdateTenantTtsSettings](/api/edge/tenants-update-tenant-tts-settings.md): Tenants_UpdateTenantTtsSettings - [Connect Toast to a tenant. Validates credentials and stores encrypted.](/api/edge/toast-connection-connect.md): Connect Toast to a tenant. Validates credentials and stores encrypted. - [Disconnect Toast from a tenant.](/api/edge/toast-connection-disconnect.md): Disconnect Toast from a tenant. - [Get the current Toast connection for a tenant.](/api/edge/toast-connection-get-connection.md): Get the current Toast connection for a tenant. - [Test the Toast connection by calling the Restaurants API.](/api/edge/toast-connection-test-connection.md): Test the Toast connection by calling the Restaurants API. - [Connect Treez to a tenant. Validates the signing material against jwt-validation and stores the private key encrypted.](/api/edge/treez-connection-connect.md): Connect Treez to a tenant. Validates the signing material against - [Disconnect Treez from a tenant.](/api/edge/treez-connection-disconnect.md): Disconnect Treez from a tenant. - [Get the current Treez connection for a tenant.](/api/edge/treez-connection-get-connection.md): Get the current Treez connection for a tenant. - [The callback URL the dispensary pastes into the Treez portal's webhook integration screen (Configurations > Config Page > Integration). Null when Pos:Treez:WebhookCallbackBaseUrl is unset or the tenant has no connection — the token itself never rides TreezConnectionInfo.](/api/edge/treez-connection-get-webhook-url.md): The callback URL the dispensary pastes into the Treez portal's webhook - [Test the Treez connection by signing a JWT and calling jwt-validation.](/api/edge/treez-connection-test-connection.md): Test the Treez connection by signing a JWT and calling jwt-validation. - [Returns the resolved default TTS voice configuration for a tenant. Used by the portal VoicePicker to show the inherited sector voice when no workspace voice is set.](/api/edge/tts-get-default-voice.md): Returns the resolved default TTS voice configuration for a tenant. - [Synthesizes speech for the given text using the tenant's configured TTS voice and settings. Language overrides are applied when available.](/api/edge/tts-synthesize.md): Synthesizes speech for the given text using the tenant's configured TTS voice and settings. - [TtsVoices_GetPreview](/api/edge/tts-voices-get-preview.md): TtsVoices_GetPreview - [TtsVoices_GetVoices](/api/edge/tts-voices-get-voices.md): TtsVoices_GetVoices - [ZammadConnection_Connect](/api/edge/zammad-connection-connect.md): ZammadConnection_Connect - [ZammadConnection_Disconnect](/api/edge/zammad-connection-disconnect.md): ZammadConnection_Disconnect - [ZammadConnection_GetConnection](/api/edge/zammad-connection-get-connection.md): ZammadConnection_GetConnection - [ZammadConnection_TestConnection](/api/edge/zammad-connection-test-connection.md): ZammadConnection_TestConnection - [Connect Zendesk to a tenant. Encrypts and stores credentials, then registers the event-subscription webhook.](/api/edge/zendesk-connection-connect.md): Connect Zendesk to a tenant. Encrypts and stores credentials, then - [Disconnect Zendesk from a tenant. Tears down the registered webhook first (best-effort, while credentials are still readable).](/api/edge/zendesk-connection-disconnect.md): Disconnect Zendesk from a tenant. Tears down the registered webhook - [Get the current Zendesk connection for a tenant.](/api/edge/zendesk-connection-get-connection.md): Get the current Zendesk connection for a tenant. - [List the tenant's Zendesk custom ticket fields (removable + active), so the portal can offer fact-key → field mappings without the merchant hand-copying field ids out of the Zendesk admin UI.](/api/edge/zendesk-connection-list-ticket-fields.md): List the tenant's Zendesk custom ticket fields (removable + active), - [Test the Zendesk connection by calling the authenticated-user endpoint.](/api/edge/zendesk-connection-test-connection.md): Test the Zendesk connection by calling the authenticated-user endpoint. - [Update the per-tenant Zendesk escalation settings (#1448): fact-key → custom-field mappings, default ticket priority, and default tags.](/api/edge/zendesk-connection-update-settings.md): Update the per-tenant Zendesk escalation settings (#1448): fact-key → - [ZohoDeskConnection_Disconnect](/api/edge/zoho-desk-connection-disconnect.md): ZohoDeskConnection_Disconnect - [The tenant's connection, or { configured: false }. 'available' says whether this environment can connect Zoho Desk at all.](/api/edge/zoho-desk-connection-get-connection.md): The tenant's connection, or { configured: false }. 'available' says - [ZohoDeskConnection_ListDepartments](/api/edge/zoho-desk-connection-list-departments.md): ZohoDeskConnection_ListDepartments - [ZohoDeskConnection_ListOrganizations](/api/edge/zoho-desk-connection-list-organizations.md): ZohoDeskConnection_ListOrganizations - [ZohoDeskConnection_SelectOrganization](/api/edge/zoho-desk-connection-select-organization.md): ZohoDeskConnection_SelectOrganization - [ZohoDeskConnection_TestConnection](/api/edge/zoho-desk-connection-test-connection.md): ZohoDeskConnection_TestConnection - [ZohoDeskConnection_UpdateSettings](/api/edge/zoho-desk-connection-update-settings.md): ZohoDeskConnection_UpdateSettings ## changelog 2026-10-07 - [Changelog](/changelog.md): 2026-10-07 ## getting-started ### authentication The Edge API accepts two kinds of credentials. Programmatic integrations use a tenant API key. Browser sessions and user-facing tools use a JWT issued by the Auth API. - [Authentication](/getting-started/authentication.md): The Edge API accepts two kinds of credentials. Programmatic integrations use a tenant API key. Browser sessions and user-facing tools use a JWT issued by the Auth API. ### channels A Merrows agent runs the same conversation definition across four channels. The engine adapts prompts and available actions per channel, and conversation authors can override behavior for a specific channel in the designer. - [Channels](/getting-started/channels.md): A Merrows agent runs the same conversation definition across four channels. The engine adapts prompts and available actions per channel, and conversation authors can override behavior for a specific channel in the designer. ### errors The APIs use conventional HTTP status codes. Error bodies are JSON; the shape varies by endpoint but always includes a human-readable message. - [Errors and rate limits](/getting-started/errors.md): The APIs use conventional HTTP status codes. Error bodies are JSON; the shape varies by endpoint but always includes a human-readable message. ### first-request This walkthrough lists your tenant's conversations. You need your tenant slug (visible in the portal URL) and an API key (how to create one). - [Your first request](/getting-started/first-request.md): This walkthrough lists your tenant's conversations. You need your tenant slug (visible in the portal URL) and an API key (how to create one). --- # Full Documentation Content # Using these docs with AI tools The site is built to be read by agents as well as people. ## Markdown everywhere[​](#markdown-everywhere "Direct link to Markdown everywhere") Every documentation page has a plain-markdown twin at the same path with a `.md` extension. For example, the [authentication guide](/getting-started/authentication.md) is also available at [`/getting-started/authentication.md`](https://docs.merrows.ai/getting-started/authentication.md). Point a scraper or an LLM at the markdown URLs and skip the HTML. Two index files cover the whole site: * [`/llms.txt`](https://docs.merrows.ai/llms.txt) lists every page with a short description. * [`/llms-full.txt`](https://docs.merrows.ai/llms-full.txt) contains the full text of the entire site in one file. The raw OpenAPI documents are downloadable too: * [`/specs/edge-consumer.json`](https://docs.merrows.ai/specs/edge-consumer.json) * [`/specs/auth.json`](https://docs.merrows.ai/specs/auth.json) ## Hosted MCP server[​](#hosted-mcp-server "Direct link to Hosted MCP server") An MCP (Model Context Protocol) server runs at: ``` https://docs.merrows.ai/mcp ``` It speaks streamable HTTP and exposes three tools: | Tool | What it does | | ------------------ | --------------------------------------------------------------------- | | `search_docs` | Full-text search across all pages, returns titles, URLs, and snippets | | `read_doc` | Returns a page's full markdown by path | | `get_openapi_spec` | Returns the Edge or Auth OpenAPI document | To add it to Claude Code: ``` claude mcp add --transport http merrows-docs https://docs.merrows.ai/mcp ``` Or in any MCP client configuration: ``` { "mcpServers": { "merrows-docs": { "type": "http", "url": "https://docs.merrows.ai/mcp" } } } ``` ## Local alternative[​](#local-alternative "Direct link to Local alternative") If you prefer not to depend on a hosted endpoint, `mcpdoc` serves the same content from the llms.txt index: ``` uvx mcpdoc --urls "MerrowsDocs:https://docs.merrows.ai/llms.txt" ``` --- # Accept an invitation ``` POST /invitations/accept ``` Authenticated. The session email must match the invited address (case-insensitive). Creates the membership with the invited role; a user already holding a role accepts without gaining a second one. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 * 403 * 409 Membership created EMAIL\_MISMATCH INVITE\_ROLE\_REMOVED --- # Add user to business ``` POST /tenants/:slug/users ``` Add a user to the business ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 201 User added --- # Apple OAuth ``` GET /auth/apple ``` Initiate Apple OAuth authentication ## Responses[​](#responses "Direct link to Responses") * 302 Redirect to Apple --- # Apple OAuth Callback ``` GET /auth/apple/callback ``` Handle Apple OAuth callback ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 302 * 400 Redirect after authentication Authentication failed --- # Check user permission ``` POST /permissions/check ``` Check if user has a specific permission in a business ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 * 400 Permission check result Missing required parameters --- # Confirm MFA enrolment (step two of two) ``` POST /auth/confirm-mfa ``` Enables the pending method on the authenticated user's own account once the submitted code checks out: a TOTP from the secret returned by /auth/setup-mfa, or the code it sent by email or SMS. A wrong code answers 400 MFA\_CONFIRM\_FAILED and changes nothing. Rate limited to 5 attempts per 15 minutes per user and 30 per hour per IP. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 * 400 * 401 * 429 MFA enabled. data carries mfa\_enabled (true) and mfa\_methods. The code did not check out (error.code MFA\_CONFIRM\_FAILED), or no enrolment is pending for the method. Not authenticated Too many attempts; see Retry-After --- # Create business role ``` POST /tenants/:slug/roles ``` Create a custom role for the business ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 201 Role created --- # Decode JWT ``` POST /decode ``` Decode and verify JWT token ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 Decoded token --- # Disable MFA ``` POST /auth/disable-mfa ``` Disable multi-factor authentication for user ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 MFA disabled --- # Facebook OAuth ``` GET /auth/facebook ``` Initiate Facebook OAuth authentication ## Responses[​](#responses "Direct link to Responses") * 302 Redirect to Facebook --- # Facebook OAuth Callback ``` GET /auth/facebook/callback ``` Handle Facebook OAuth callback ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 302 * 400 Redirect after authentication Authentication failed --- # Get all available permissions ``` GET /permissions/available/all ``` Get all permissions available in the system ## Responses[​](#responses "Direct link to Responses") * 200 Available permissions --- # Get business ``` GET /tenants/:slug ``` Get business details by slug ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 * 404 Business details Business not found --- # Get business roles ``` GET /tenants/:slug/roles ``` List all roles in a business ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 Role list --- # Get business users ``` GET /tenants/:slug/users ``` List all users in a business ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 User list --- # Get my businesses ``` GET /tenants/my-tenants ``` List all businesses for authenticated user ## Responses[​](#responses "Direct link to Responses") * 200 Business list --- # Get user permissions for business ``` GET /permissions/:businessId ``` Get user's permissions for a specific business ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 * 403 * 404 User permissions Access denied Business not found --- # Google OAuth ``` GET /auth/google ``` Initiate Google OAuth authentication ## Responses[​](#responses "Direct link to Responses") * 302 Redirect to Google --- # Google OAuth Callback ``` GET /auth/google/callback ``` Handle Google OAuth callback ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 302 * 400 Redirect after authentication Authentication failed --- # Invite a member by email ``` POST /tenants/:slug/invitations ``` Create a pending invitation and email an accept link. The invitee needs no account yet; accepting requires signing in with the invited address. Requires auth.users.manage (or global admin); owner roles require an owner actor. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 201 * 409 Invitation created (emailSent flags delivery) ALREADY\_MEMBER or DUPLICATE\_INVITE --- # List member invitations ``` GET /tenants/:slug/invitations ``` All invitations for the tenant, newest first; pending rows past expiry carry expired=true. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 Invitation list --- # List roles ``` GET /roles ``` Get all available roles ## Responses[​](#responses "Direct link to Responses") * 200 Role list --- # Logout user ``` POST /auth/logout ``` Invalidate user session and token ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 Logout successful --- Version: 2.0.0 Export * [OpenAPI Spec](/specs/auth.json) # Merrows Auth API Authentication and business management API with unified MFA support ## Authentication[​](#authentication "Direct link to Authentication") * API Key: Bearer Enter JWT token with Bearer prefix | Security Scheme Type: | apiKey | | ---------------------- | ------------- | | Header parameter name: | Authorization | --- # Microsoft OAuth ``` GET /auth/microsoft ``` Initiate Microsoft OAuth authentication ## Responses[​](#responses "Direct link to Responses") * 302 Redirect to Microsoft --- # Microsoft OAuth Callback ``` GET /auth/microsoft/callback ``` Handle Microsoft OAuth callback ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 302 * 400 Redirect after authentication Authentication failed --- # Register new user ``` POST /auth/register ``` Create a new user account with email or phone number ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 201 * 400 Registration successful Validation error --- # Remove user from business ``` DELETE /tenants/:slug/users/:userIdentifier ``` Remove a user from the business ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 User removed --- # Request password reset ``` POST /auth/forgot-password ``` Send password reset code to user's email or phone ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 Reset code sent --- # Resend a pending invitation ``` POST /tenants/:slug/invitations/:id/resend ``` Rotates the token, extends the expiry, and emails a fresh accept link. The previously emailed link stops working. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 Invitation resent --- # Resend verification code ``` POST /auth/resend-verification ``` Resend verification code to email or phone ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 Code sent successfully --- # Reset password ``` POST /auth/reset-password ``` Reset password using verification code ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 Password reset successful --- # Revoke a pending invitation ``` DELETE /tenants/:slug/invitations/:id ``` Soft-revokes a pending invitation. Owner-role invitations require an owner actor. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 Invitation revoked --- # Set active business ``` POST /permissions/set-active-tenant ``` Set user's active business context ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 * 403 * 404 Active business updated Access denied Business not found --- # Start MFA enrolment (step one of two) ``` POST /auth/setup-mfa ``` Begins enrolling a second factor on the authenticated user's own account (#2500). Nothing is enabled by this call. For `authenticator` a TOTP secret is stored and returned with its otpauth URI; for `email` or `sms` a code is sent to the verified contact. Call POST /auth/confirm-mfa with a code from the method to enable it. The user is taken from the JWT; a body-supplied userId is ignored. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 * 400 Enrolment started. data carries mfa\_enabled and mfa\_methods (both unchanged), pending\_methods, totp { secret, otpauthUri } when authenticator was requested, and delivery \[{ method, delivered, expiresAt }] for email/sms. A requested method is already enabled on the account, its contact is not verified, or the code could not be sent. --- # TikTok OAuth ``` GET /auth/tiktok ``` Initiate TikTok OAuth authentication ## Responses[​](#responses "Direct link to Responses") * 302 Redirect to TikTok --- # TikTok OAuth Callback ``` GET /auth/tiktok/callback ``` Handle TikTok OAuth callback ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 302 * 400 Redirect after authentication Authentication failed --- # Update user role ``` PUT /tenants/:slug/users/:userIdentifier/role ``` Update user's role in business ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 Role updated --- # User login ``` POST /auth/login ``` Authenticate user with email/phone and password ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 * 401 * 503 Login successful Invalid credentials MFA challenge store unavailable (error.code MFA\_STORE\_UNAVAILABLE). The account is MFA-enrolled and the service's Redis client is not ready; no code was sent. Retry after the Retry-After header (seconds). --- # Verify an invitation token ``` GET /invitations/verify ``` Public. Returns tenant, role, inviter, and invited email for a pending, unexpired token; anything else is a uniform 404. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 * 404 Invitation context INVALID\_INVITE --- # Verify email or phone ``` POST /auth/verify ``` Verify user's email or phone number with code ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 * 400 Verification successful Invalid or expired code --- # Verify JWT token ``` GET /auth/verify-token ``` Check if JWT token is valid ## Responses[​](#responses "Direct link to Responses") * 200 * 401 Token is valid Invalid token --- # Verify MFA challenge ``` POST /auth/verify-mfa ``` Verify multi-factor authentication codes ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 * 503 MFA verified successfully MFA challenge store unavailable (error.code MFA\_STORE\_UNAVAILABLE). The service's Redis client is not ready, so the challenge could not be consumed; the challenge is still valid. Retry after the Retry-After header (seconds). --- # Lists all active action definitions. Optionally filter by domain. ``` GET /api/actions ``` Lists all active action definitions. Optionally filter by domain. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # #514 automation-rate KPI: per-task outcomes from the #512 scoring pipeline rolled into automation / bot-failure / abandonment rates (appropriate escalations excluded from the denominator per the #509 metric contract), totalled, by UTC day, and by channel. Observational — every cell traces back to scored tasks via the tasks endpoint below. ``` GET /api/analytics/tenants/:tenantSlug/automation-rate ``` \#514 automation-rate KPI: per-task outcomes from the #512 scoring pipeline rolled into automation / bot-failure / abandonment rates (appropriate escalations excluded from the denominator per the #509 metric contract), totalled, by UTC day, and by channel. Observational — every cell traces back to scored tasks via the tasks endpoint below. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Drill-down for the KPI: the scored tasks behind a rate cell, filterable by outcome/channel, newest first. Each row links to the conversation transcript via conversation\_id (= the analytics CallId) and carries the task's turn span. ``` GET /api/analytics/tenants/:tenantSlug/automation-rate/tasks ``` Drill-down for the KPI: the scored tasks behind a rate cell, filterable by outcome/channel, newest first. Each row links to the conversation transcript via conversation\_id (= the analytics CallId) and carries the task's turn span. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # What the scored tasks in the window did, for the owner's analytics page: tasks that completed each kind of action (an order placed, a return opened, an appointment booked), and escalated tasks by how the handoff ended. Counts are tasks, in the same window and filters as automation-rate, and each one drills through automation-rate/tasks with \`action\` or \`handoff\`. A handoff that stopped at the business's own setup is reported as such, never as completed work. ``` GET /api/analytics/tenants/:tenantSlug/automation-rate/work ``` What the scored tasks in the window did, for the owner's analytics page: tasks that completed each kind of action (an order placed, a return opened, an appointment booked), and escalated tasks by how the handoff ended. Counts are tasks, in the same window and filters as automation-rate, and each one drills through automation-rate/tasks with `action` or `handoff`. A handoff that stopped at the business's own setup is reported as such, never as completed work. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Retrieves call analytics data for a specific tenant based on a set of query parameters. This endpoint allows filtering calls by date range, flow ID, outcome, language, and translation status. ``` GET /api/analytics/tenants/:tenantSlug/calls ``` Retrieves call analytics data for a specific tenant based on a set of query parameters. This endpoint allows filtering calls by date range, flow ID, outcome, language, and translation status. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Merchant-facing CSAT rollup. Customer votes and AI estimates are returned as separate, scale-labelled metrics and are never averaged together or across unlike scales. ``` GET /api/analytics/tenants/:tenantSlug/csat ``` Merchant-facing CSAT rollup. Customer votes and AI estimates are returned as separate, scale-labelled metrics and are never averaged together or across unlike scales. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Create a tenant-scoped API key ``` POST /api/tenants/:tenantSlug/api-keys ``` Create a tenant-scoped API key ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # List API keys for a tenant ``` GET /api/tenants/:tenantSlug/api-keys ``` List API keys for a tenant ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Revoke a tenant API key ``` DELETE /api/tenants/:tenantSlug/api-keys/:keyId ``` Revoke a tenant API key ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Add a channel add-on (voice, SMS or the phone line) to a live subscription (#2780). ``` POST /api/tenants/:tenantSlug/billing/addons ``` Add a channel add-on (voice, SMS or the phone line) to a live subscription (#2780). ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Move a live subscription to another plan through Stripe's subscription update API (#2780). Upgrades are prorated now; downgrades take effect next period. Never opens a second Checkout. ``` POST /api/tenants/:tenantSlug/billing/subscription/plan ``` Move a live subscription to another plan through Stripe's subscription update API (#2780). Upgrades are prorated now; downgrades take effect next period. Never opens a second Checkout. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Billing\_CreatePortalSession ``` POST /api/tenants/:tenantSlug/billing/portal-session ``` Billing\_CreatePortalSession ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # The plans and the channel add-ons (#2780). ``` GET /api/tenants/:tenantSlug/billing/plans ``` The plans and the channel add-ons (#2780). ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Billing\_GetReloadPacks ``` GET /api/tenants/:tenantSlug/billing/reload-packs ``` Billing\_GetReloadPacks ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Billing\_GetSummary ``` GET /api/tenants/:tenantSlug/billing/summary ``` Billing\_GetSummary ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Remove a channel add-on (#2780). The channel stays on until the paid period ends; the number is held for 90 days after that. ``` DELETE /api/tenants/:tenantSlug/billing/addons/:addonSlug ``` Remove a channel add-on (#2780). The channel stays on until the paid period ends; the number is held for 90 days after that. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Billing\_StartReloadCheckout ``` POST /api/tenants/:tenantSlug/billing/checkout/reload ``` Billing\_StartReloadCheckout ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Billing\_StartSubscriptionCheckout ``` POST /api/tenants/:tenantSlug/billing/checkout/subscription ``` Billing\_StartSubscriptionCheckout ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Connect Blaze to a tenant. Validates the keys against GET /partner/store and stores both encrypted; registers order webhooks best-effort when the environment has a callback base URL configured. ``` POST /api/tenants/:tenantSlug/blaze/connections ``` Connect Blaze to a tenant. Validates the keys against GET /partner/store and stores both encrypted; registers order webhooks best-effort when the environment has a callback base URL configured. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Disconnect Blaze from a tenant. ``` DELETE /api/tenants/:tenantSlug/blaze/connections ``` Disconnect Blaze from a tenant. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Get the current Blaze connection for a tenant. ``` GET /api/tenants/:tenantSlug/blaze/connections ``` Get the current Blaze connection for a tenant. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Test the Blaze connection by calling GET /partner/store with the stored keys. ``` POST /api/tenants/:tenantSlug/blaze/connections/test ``` Test the Blaze connection by calling GET /partner/store with the stored keys. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Connect a booking provider. Encrypts + stores credentials and sets the active provider. ``` POST /api/tenants/:tenantSlug/integrations/booking ``` Connect a booking provider. Encrypts + stores credentials and sets the active provider. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Disconnect the tenant's booking provider and clear the active provider. ``` DELETE /api/tenants/:tenantSlug/integrations/booking ``` Disconnect the tenant's booking provider and clear the active provider. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Get the tenant's current booking connection (200 with null body if unconfigured). ``` GET /api/tenants/:tenantSlug/integrations/booking ``` Get the tenant's current booking connection (200 with null body if unconfigured). ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Capabilities\_Delete ``` DELETE /api/tenants/:tenantSlug/capabilities/:capabilityName ``` Capabilities\_Delete ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Capabilities\_Get ``` GET /api/tenants/:tenantSlug/capabilities/:capabilityName ``` Capabilities\_Get ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Capabilities\_List ``` GET /api/tenants/:tenantSlug/capabilities ``` Capabilities\_List ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Capabilities\_Update ``` PUT /api/tenants/:tenantSlug/capabilities/:capabilityName ``` Capabilities\_Update ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Retrieves the conversation settings for a specific tenant. This includes settings like dead-air thresholds, TTS chunk thresholds, and global DTMF overrides. ``` GET /api/tenants/:tenantSlug/conversation-settings ``` Retrieves the conversation settings for a specific tenant. This includes settings like dead-air thresholds, TTS chunk thresholds, and global DTMF overrides. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Retrieves the menu item clarification settings for a specific tenant. Controls how the bot handles variations, modifiers, and ambiguous item matches. ``` GET /api/tenants/:tenantSlug/conversation-settings/clarification ``` Retrieves the menu item clarification settings for a specific tenant. Controls how the bot handles variations, modifiers, and ambiguous item matches. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Creates or updates the conversation settings for a specific tenant. This allows for fine-tuning conversation behavior and DTMF handling. ``` PUT /api/tenants/:tenantSlug/conversation-settings ``` Creates or updates the conversation settings for a specific tenant. This allows for fine-tuning conversation behavior and DTMF handling. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Updates the menu item clarification settings for a specific tenant. Only provided fields will be updated; others retain their current values. ``` PUT /api/tenants/:tenantSlug/conversation-settings/clarification ``` Updates the menu item clarification settings for a specific tenant. Only provided fields will be updated; others retain their current values. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Retrieves the session summary for a specific call. The session summary contains metadata about the conversation, such as the start and end times, duration, and outcome. ``` GET /api/tenants/:tenantSlug/calls/:callId/transcript/session ``` Retrieves the session summary for a specific call. The session summary contains metadata about the conversation, such as the start and end times, duration, and outcome. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Retrieves the transcript for a specific call. The transcript can be filtered by speaker and turn number, and returned in either a compact or verbose format. ``` GET /api/tenants/:tenantSlug/calls/:callId/transcript ``` Retrieves the transcript for a specific call. The transcript can be filtered by speaker and turn number, and returned in either a compact or verbose format. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Removes conversation-level TTS settings, reverting to the tenant default. ``` DELETE /api/tenants/:tenantSlug/conversations/:conversationSlug/tts-settings ``` Removes conversation-level TTS settings, reverting to the tenant default. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 204 * 404 No Content Not Found --- # Gets the TTS settings for a conversation, optionally pinned to a version. Returns the version-specific row if it exists, otherwise the version-agnostic row. ``` GET /api/tenants/:tenantSlug/conversations/:conversationSlug/tts-settings ``` Gets the TTS settings for a conversation, optionally pinned to a version. Returns the version-specific row if it exists, otherwise the version-agnostic row. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 * 404 OK Not Found --- # Creates or updates TTS settings for a conversation. Only provided (non-null) fields are written; omitted fields retain their current value on update. ``` PUT /api/tenants/:tenantSlug/conversations/:conversationSlug/tts-settings ``` Creates or updates TTS settings for a conversation. Only provided (non-null) fields are written; omitted fields retain their current value on update. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 * 404 OK Not Found --- # Create a new draft conversation. ``` POST /api/tenants/:tenantSlug/conversations ``` Create a new draft conversation. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Delete a never-published draft conversation (#354). Published conversations return 409; create-and-abandon drafts are the only hard-deletable state. ``` DELETE /api/tenants/:tenantSlug/conversations/:slug ``` Delete a never-published draft conversation (#354). Published conversations return 409; create-and-abandon drafts are the only hard-deletable state. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Compute a structural diff between two versions of a conversation. ``` GET /api/tenants/:tenantSlug/conversations/:slug/versions/:fromVersion/diff/:toVersion ``` Compute a structural diff between two versions of a conversation. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Get a specific conversation by slug or ID (returns latest version). ``` GET /api/tenants/:tenantSlug/conversations/:slugOrId ``` Get a specific conversation by slug or ID (returns latest version). ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # List all conversations for a tenant. ``` GET /api/tenants/:tenantSlug/conversations ``` List all conversations for a tenant. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # List all versions for a conversation slug. ``` GET /api/tenants/:tenantSlug/conversations/:slug/versions ``` List all versions for a conversation slug. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Publish a draft conversation, creating a new immutable version. ``` POST /api/tenants/:tenantSlug/conversations/:slugOrId/publish ``` Publish a draft conversation, creating a new immutable version. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Rollback a conversation to a specific version, creating a new version with the target's definition. ``` POST /api/tenants/:tenantSlug/conversations/:slug/versions/:version/rollback ``` Rollback a conversation to a specific version, creating a new version with the target's definition. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Update an existing draft conversation. ``` PUT /api/tenants/:tenantSlug/conversations/:slugOrId ``` Update an existing draft conversation. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # EmailConversations\_Close ``` POST /api/tenants/:tenantSlug/email-conversations/:id/close ``` EmailConversations\_Close ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Escalate an email conversation to the helpdesk provider. Builds transcript from the full message thread and creates a helpdesk ticket. ``` POST /api/tenants/:tenantSlug/email-conversations/:id/escalate ``` Escalate an email conversation to the helpdesk provider. Builds transcript from the full message thread and creates a helpdesk ticket. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # EmailConversations\_Get ``` GET /api/tenants/:tenantSlug/email-conversations/:id ``` EmailConversations\_Get ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # EmailConversations\_List ``` GET /api/tenants/:tenantSlug/email-conversations ``` EmailConversations\_List ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # EmailConversations\_Reply ``` POST /api/tenants/:tenantSlug/email-conversations/:id/reply ``` EmailConversations\_Reply ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Get a single delivery log entry. ``` GET /api/tenants/:tenantSlug/email-deliveries/:id ``` Get a single delivery log entry. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # List email delivery logs with optional filters. ``` GET /api/tenants/:tenantSlug/email-deliveries ``` List email delivery logs with optional filters. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Get aggregate delivery stats for a tenant. ``` GET /api/tenants/:tenantSlug/email-deliveries/stats ``` Get aggregate delivery stats for a tenant. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Get current email settings for a tenant ``` GET /api/tenants/:tenantSlug/email-settings ``` Get current email settings for a tenant ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Get provider-specific email forwarding setup guide ``` GET /api/tenants/:tenantSlug/email-settings/setup-guide ``` Get provider-specific email forwarding setup guide ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Get forwarding verification status for a tenant ``` GET /api/tenants/:tenantSlug/email-settings/verify-forwarding ``` Get forwarding verification status for a tenant ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # List recent inbound emails for a tenant ``` GET /api/tenants/:tenantSlug/email-settings/inbound-emails ``` List recent inbound emails for a tenant ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Start email forwarding verification — sends a verification email to the external address. When that address is forwarded to the tenant's inbound address the webhook auto-detects the token and marks the verification complete. ``` POST /api/tenants/:tenantSlug/email-settings/verify-forwarding ``` Start email forwarding verification — sends a verification email to the external address. When that address is forwarded to the tenant's inbound address the webhook auto-detects the token and marks the verification complete. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Update email settings for a tenant. The inbound routing address is NOT writable here (#1361): it is the identity the webhook matches inbound mail against, and the old single-column design let the editable reply-from field silently overwrite it. Custom inbound addresses are an operator concern; reply-from is the merchant-facing setting. ``` PUT /api/tenants/:tenantSlug/email-settings ``` Update email settings for a tenant. The inbound routing address is NOT writable here (#1361): it is the identity the webhook matches inbound mail against, and the old single-column design let the editable reply-from field silently overwrite it. Custom inbound addresses are an operator concern; reply-from is the merchant-facing setting. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # EmailTemplates\_Create ``` POST /api/tenants/:tenantSlug/email-templates ``` EmailTemplates\_Create ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # EmailTemplates\_Delete ``` DELETE /api/tenants/:tenantSlug/email-templates/:id ``` EmailTemplates\_Delete ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # EmailTemplates\_Get ``` GET /api/tenants/:tenantSlug/email-templates/:id ``` EmailTemplates\_Get ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # EmailTemplates\_List ``` GET /api/tenants/:tenantSlug/email-templates ``` EmailTemplates\_List ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Render a template with sample variables and return the branded HTML preview. ``` POST /api/tenants/:tenantSlug/email-templates/:id/preview ``` Render a template with sample variables and return the branded HTML preview. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Send a test email using this template. ``` POST /api/tenants/:tenantSlug/email-templates/:id/send-test ``` Send a test email using this template. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # EmailTemplates\_Update ``` PUT /api/tenants/:tenantSlug/email-templates/:id ``` EmailTemplates\_Update ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # EmbedConnection\_CreateOrRotateKey ``` POST /api/tenants/:tenantSlug/embed/key ``` EmbedConnection\_CreateOrRotateKey ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # EmbedConnection\_Get ``` GET /api/tenants/:tenantSlug/embed ``` EmbedConnection\_Get ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 * 404 OK Not Found --- # Embed usage rollup (#830): sessions/messages/top-origins from the Mongo analytics documents stamped Source = 'website\_embed'. Message counts cover persisted (ended) sessions only; live sessions appear in the session count with 0 messages until their transcript persists. ``` GET /api/tenants/:tenantSlug/embed/analytics ``` Embed usage rollup (#830): sessions/messages/top-origins from the Mongo analytics documents stamped Source = "website\_embed". Message counts cover persisted (ended) sessions only; live sessions appear in the session count with 0 messages until their transcript persists. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 * 404 OK Not Found --- # EmbedConnection\_Update ``` PUT /api/tenants/:tenantSlug/embed ``` EmbedConnection\_Update ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 * 404 OK Not Found --- # Add a variant to an experiment. ``` POST /api/tenants/:tenantSlug/experiments/:experimentId/variants ``` Add a variant to an experiment. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Conclude an experiment with an optional winning variant. If promoteWinner is true, updates the TenantConversationAssignment. ``` POST /api/tenants/:tenantSlug/experiments/:experimentId/conclude ``` Conclude an experiment with an optional winning variant. If promoteWinner is true, updates the TenantConversationAssignment. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Create a new experiment in draft status. ``` POST /api/tenants/:tenantSlug/experiments ``` Create a new experiment in draft status. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Delete a draft experiment. ``` DELETE /api/tenants/:tenantSlug/experiments/:experimentId ``` Delete a draft experiment. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Remove a variant. ``` DELETE /api/tenants/:tenantSlug/experiments/:experimentId/variants/:variantId ``` Remove a variant. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Get experiment details including variants and assignment counts. ``` GET /api/tenants/:tenantSlug/experiments/:experimentId ``` Get experiment details including variants and assignment counts. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # List all experiments for a tenant, including variant counts. ``` GET /api/tenants/:tenantSlug/experiments ``` List all experiments for a tenant, including variant counts. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Pause a running experiment. ``` POST /api/tenants/:tenantSlug/experiments/:experimentId/pause ``` Pause a running experiment. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Get assignment counts per variant for an experiment. ``` GET /api/tenants/:tenantSlug/experiments/:experimentId/results ``` Get assignment counts per variant for an experiment. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Resume a paused experiment. ``` POST /api/tenants/:tenantSlug/experiments/:experimentId/resume ``` Resume a paused experiment. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Start an experiment. Validates: weights sum to 100, >= 2 variants, no other running experiment for tenant. ``` POST /api/tenants/:tenantSlug/experiments/:experimentId/start ``` Start an experiment. Validates: weights sum to 100, >= 2 variants, no other running experiment for tenant. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Update a draft experiment. Returns 409 if not in draft status. ``` PUT /api/tenants/:tenantSlug/experiments/:experimentId ``` Update a draft experiment. Returns 409 if not in draft status. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Update a variant. ``` PUT /api/tenants/:tenantSlug/experiments/:experimentId/variants/:variantId ``` Update a variant. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Connect Gladly to a tenant. Encrypts and stores credentials. Optionally registers webhook with Gladly. ``` POST /api/tenants/:tenantSlug/gladly/connections ``` Connect Gladly to a tenant. Encrypts and stores credentials. Optionally registers webhook with Gladly. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Disconnect Gladly from a tenant. ``` DELETE /api/tenants/:tenantSlug/gladly/connections ``` Disconnect Gladly from a tenant. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Get the current Gladly connection for a tenant. ``` GET /api/tenants/:tenantSlug/gladly/connections ``` Get the current Gladly connection for a tenant. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Test the Gladly connection by calling the agents endpoint. ``` POST /api/tenants/:tenantSlug/gladly/connections/test ``` Test the Gladly connection by calling the agents endpoint. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Connect Gorgias to a tenant. Encrypts and stores credentials. ``` POST /api/tenants/:tenantSlug/gorgias/connections ``` Connect Gorgias to a tenant. Encrypts and stores credentials. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Disconnect Gorgias from a tenant. ``` DELETE /api/tenants/:tenantSlug/gorgias/connections ``` Disconnect Gorgias from a tenant. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Get the current Gorgias connection for a tenant. ``` GET /api/tenants/:tenantSlug/gorgias/connections ``` Get the current Gorgias connection for a tenant. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Test the Gorgias connection by calling the account endpoint. ``` POST /api/tenants/:tenantSlug/gorgias/connections/test ``` Test the Gorgias connection by calling the account endpoint. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Add a note to an existing helpdesk conversation. ``` POST /api/tenants/:tenantSlug/helpdesk/conversations/:conversationId/notes ``` Add a note to an existing helpdesk conversation. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Create a report export job. ``` POST /api/tenants/:tenantSlug/helpdesk/reports ``` Create a report export job. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Manually escalate to helpdesk from the portal. ``` POST /api/tenants/:tenantSlug/helpdesk/escalate ``` Manually escalate to helpdesk from the portal. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Get a single conversation link by ID. ``` GET /api/tenants/:tenantSlug/helpdesk/conversations/:id ``` Get a single conversation link by ID. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Check status of a report job. ``` GET /api/tenants/:tenantSlug/helpdesk/reports/:jobId ``` Check status of a report job. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # List agents from the helpdesk provider. ``` GET /api/tenants/:tenantSlug/helpdesk/agents ``` List agents from the helpdesk provider. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # List conversation links (escalation history) for the tenant. ``` GET /api/tenants/:tenantSlug/helpdesk/conversations ``` List conversation links (escalation history) for the tenant. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # List inboxes from the helpdesk provider. ``` GET /api/tenants/:tenantSlug/helpdesk/inboxes ``` List inboxes from the helpdesk provider. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # IntegrationCapabilities\_Get ``` GET /api/tenants/:tenantSlug/integrations/capabilities ``` IntegrationCapabilities\_Get ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Removes a per-tenant override for a system intent, resetting it to system defaults. ``` DELETE /api/tenants/:tenantSlug/intent-catalog/:intentName/override ``` Removes a per-tenant override for a system intent, resetting it to system defaults. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Returns the full system intent catalog for this tenant's type, including override metadata (enabled/disabled, custom description/examples). ``` GET /api/tenants/:tenantSlug/intent-catalog ``` Returns the full system intent catalog for this tenant's type, including override metadata (enabled/disabled, custom description/examples). ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Creates or updates a per-tenant override for a system intent. Use this to enable/disable intents or customize their description/examples. ``` PUT /api/tenants/:tenantSlug/intent-catalog/:intentName/override ``` Creates or updates a per-tenant override for a system intent. Use this to enable/disable intents or customize their description/examples. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Connect Kustomer to a tenant. Encrypts and stores the API token. ``` POST /api/tenants/:tenantSlug/kustomer/connections ``` Connect Kustomer to a tenant. Encrypts and stores the API token. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Disconnect Kustomer from a tenant. ``` DELETE /api/tenants/:tenantSlug/kustomer/connections ``` Disconnect Kustomer from a tenant. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Get the current Kustomer connection for a tenant. ``` GET /api/tenants/:tenantSlug/kustomer/connections ``` Get the current Kustomer connection for a tenant. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Test the Kustomer connection by calling the current user endpoint. ``` POST /api/tenants/:tenantSlug/kustomer/connections/test ``` Test the Kustomer connection by calling the current user endpoint. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # LlmPrompts\_Delete ``` DELETE /api/tenants/:tenantSlug/llm-prompts/:promptKey ``` LlmPrompts\_Delete ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # LlmPrompts\_Get ``` GET /api/tenants/:tenantSlug/llm-prompts/:promptKey ``` LlmPrompts\_Get ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # LlmPrompts\_List ``` GET /api/tenants/:tenantSlug/llm-prompts ``` LlmPrompts\_List ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # LlmPrompts\_Update ``` PUT /api/tenants/:tenantSlug/llm-prompts/:promptKey ``` LlmPrompts\_Update ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Connect Meadow to a tenant. Validates the keys and stores them encrypted. ``` POST /api/tenants/:tenantSlug/meadow/connections ``` Connect Meadow to a tenant. Validates the keys and stores them encrypted. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Disconnect Meadow from a tenant. ``` DELETE /api/tenants/:tenantSlug/meadow/connections ``` Disconnect Meadow from a tenant. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Get the current Meadow connection for a tenant. ``` GET /api/tenants/:tenantSlug/meadow/connections ``` Get the current Meadow connection for a tenant. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Test the Meadow connection by calling the organization endpoint. ``` POST /api/tenants/:tenantSlug/meadow/connections/test ``` Test the Meadow connection by calling the organization endpoint. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- Version: v1 Export * [OpenAPI Spec](/specs/edge-consumer.json) # Merrows Edge API Public API for building on the Merrows platform: conversations, analytics, transcripts, experiments, telephony, email/SMS templates, and integration management. ## Authentication[​](#authentication "Direct link to Authentication") * API Key: Bearer * API Key: ApiKey JWT Authorization header using the Bearer scheme. Example: "Bearer {token}" | Security Scheme Type: | apiKey | | ---------------------- | ------------- | | Header parameter name: | Authorization | API key authentication via the X-Api-Key header. Tenant keys are prefixed "rgl\_tenant\_". | Security Scheme Type: | apiKey | | ---------------------- | --------- | | Header parameter name: | X-Api-Key | --- # Preview return financials before creating. Returns 409 if tenant uses Redo as returns provider. ``` POST /api/tenants/:tenantSlug/oms/orders/:orderId/return/calculate ``` Preview return financials before creating. Returns 409 if tenant uses Redo as returns provider. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Cancel an order (irreversible) ``` POST /api/tenants/:tenantSlug/oms/orders/:orderId/cancel ``` Cancel an order (irreversible) ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Cancel a subscription ``` POST /api/tenants/:tenantSlug/oms/subscriptions/:subscriptionId/cancel ``` Cancel a subscription ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Create an exchange (return items + ship new items). Returns 409 if tenant uses Redo as returns provider. ``` POST /api/tenants/:tenantSlug/oms/orders/:orderId/exchange ``` Create an exchange (return items + ship new items). Returns 409 if tenant uses Redo as returns provider. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Create a return request for an order. Returns 409 if tenant uses Redo as returns provider. ``` POST /api/tenants/:tenantSlug/oms/orders/:orderId/return ``` Create a return request for an order. Returns 409 if tenant uses Redo as returns provider. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Get order details with fulfillments and tracking info ``` GET /api/tenants/:tenantSlug/oms/orders/:orderId ``` Get order details with fulfillments and tracking info ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Get subscription details ``` GET /api/tenants/:tenantSlug/oms/subscriptions/:subscriptionId ``` Get subscription details ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # List subscriptions for a customer ``` GET /api/tenants/:tenantSlug/oms/subscriptions ``` List subscriptions for a customer ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Pause a subscription ``` POST /api/tenants/:tenantSlug/oms/subscriptions/:subscriptionId/pause ``` Pause a subscription ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Process/confirm a return (disposition + refund). Returns 409 if tenant uses Redo as returns provider. ``` POST /api/tenants/:tenantSlug/oms/orders/:orderId/return/process ``` Process/confirm a return (disposition + refund). Returns 409 if tenant uses Redo as returns provider. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Resume a paused subscription ``` POST /api/tenants/:tenantSlug/oms/subscriptions/:subscriptionId/resume ``` Resume a paused subscription ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Search orders by email, phone, name, or status ``` GET /api/tenants/:tenantSlug/oms/orders ``` Search orders by email, phone, name, or status ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Skip the next shipment/charge on a subscription (#1507). Returns 501 when the resolved provider has no skip support (OMS bridge). ``` POST /api/tenants/:tenantSlug/oms/subscriptions/:subscriptionId/skip ``` Skip the next shipment/charge on a subscription (#1507). Returns 501 when the resolved provider has no skip support (OMS bridge). ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Swap the product variant on a subscription (#1507). Returns 501 when the resolved provider has no swap support (OMS bridge). ``` POST /api/tenants/:tenantSlug/oms/subscriptions/:subscriptionId/swap ``` Swap the product variant on a subscription (#1507). Returns 501 when the resolved provider has no swap support (OMS bridge). ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Restore a previously skipped shipment/charge on a subscription (#1507). Returns 501 when the resolved provider has no skip support (OMS bridge). ``` POST /api/tenants/:tenantSlug/oms/subscriptions/:subscriptionId/unskip ``` Restore a previously skipped shipment/charge on a subscription (#1507). Returns 501 when the resolved provider has no skip support (OMS bridge). ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # OutboundCalls\_GetStatus ``` GET /api/tenants/:tenantSlug/calls/outbound/:callId/status ``` OutboundCalls\_GetStatus ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 * 404 OK Not Found --- # OutboundCalls\_Hangup ``` POST /api/tenants/:tenantSlug/calls/outbound/:callId/hangup ``` OutboundCalls\_Hangup ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 * 404 OK Not Found --- # OutboundCalls\_InitiateCall ``` POST /api/tenants/:tenantSlug/calls/outbound ``` OutboundCalls\_InitiateCall ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 202 * 400 * 403 * 409 * 503 Accepted Bad Request Forbidden Conflict Service Unavailable --- # Creates an order with a list of items and sends a payment link to the customer via SMS. ``` POST /api/tenants/:tenantSlug/payments/orders/create-with-payment-link ``` Creates an order with a list of items and sends a payment link to the customer via SMS. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Creates a quick payment link for a simple amount and sends it to the customer via SMS. ``` POST /api/tenants/:tenantSlug/payments/quick-payment-link ``` Creates a quick payment link for a simple amount and sends it to the customer via SMS. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Retrieves the status of a specific payment link. ``` GET /api/tenants/:tenantSlug/payments/payment-links/:paymentLinkId/status ``` Retrieves the status of a specific payment link. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # An example endpoint demonstrating how a voice order can be processed and converted into a payment link. ``` POST /api/tenants/:tenantSlug/payments/voice-order ``` An example endpoint demonstrating how a voice order can be processed and converted into a payment link. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Creates a new order in the Point of Sale (POS) system for a specific tenant. ``` POST /api/tenants/:tenantSlug/pos/orders ``` Creates a new order in the Point of Sale (POS) system for a specific tenant. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Retrieves the menu for a specific tenant and location from the configured Point of Sale (POS) system. ``` GET /api/tenants/:tenantSlug/pos/menu ``` Retrieves the menu for a specific tenant and location from the configured Point of Sale (POS) system. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Retrieves a specific order from the Point of Sale (POS) system. ``` GET /api/tenants/:tenantSlug/pos/orders/:orderId ``` Retrieves a specific order from the Point of Sale (POS) system. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Connect POSaBIT to a tenant. Validates the venue credentials and stores encrypted. ``` POST /api/tenants/:tenantSlug/posabit/connections ``` Connect POSaBIT to a tenant. Validates the venue credentials and stores encrypted. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Disconnect POSaBIT from a tenant. ``` DELETE /api/tenants/:tenantSlug/posabit/connections ``` Disconnect POSaBIT from a tenant. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Get the current POSaBIT connection for a tenant. ``` GET /api/tenants/:tenantSlug/posabit/connections ``` Get the current POSaBIT connection for a tenant. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Test the POSaBIT connection by calling the venue info endpoint. ``` POST /api/tenants/:tenantSlug/posabit/connections/test ``` Test the POSaBIT connection by calling the venue info endpoint. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Connect Recharge to a tenant. Verifies the token against the live API first, then encrypts and stores it. ``` POST /api/tenants/:tenantSlug/recharge/connections ``` Connect Recharge to a tenant. Verifies the token against the live API first, then encrypts and stores it. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Disconnect Recharge from a tenant (soft: the row survives for revive). ``` DELETE /api/tenants/:tenantSlug/recharge/connections ``` Disconnect Recharge from a tenant (soft: the row survives for revive). ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Get the current Recharge connection for a tenant. ``` GET /api/tenants/:tenantSlug/recharge/connections ``` Get the current Recharge connection for a tenant. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Test the stored Recharge connection with an authenticated store read. ``` POST /api/tenants/:tenantSlug/recharge/connections/test ``` Test the stored Recharge connection with an authenticated store read. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Update the display-only settings on the active connection. ``` PUT /api/tenants/:tenantSlug/recharge/connections/settings ``` Update the display-only settings on the active connection. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Connect Redo to a tenant. Encrypts and stores API token, store ID, and webhook secret. Optionally registers webhook with Redo API. ``` POST /api/tenants/:tenantSlug/redo/connections ``` Connect Redo to a tenant. Encrypts and stores API token, store ID, and webhook secret. Optionally registers webhook with Redo API. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Disconnect Redo from a tenant ``` DELETE /api/tenants/:tenantSlug/redo/connections ``` Disconnect Redo from a tenant ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Get the current Redo connection for a tenant ``` GET /api/tenants/:tenantSlug/redo/connections ``` Get the current Redo connection for a tenant ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Get the customer return portal URL for this tenant. ``` GET /api/tenants/:tenantSlug/returns/portal-link ``` Get the customer return portal URL for this tenant. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Get a single return case by its external return ID, with event history. ``` GET /api/tenants/:tenantSlug/returns/:returnId ``` Get a single return case by its external return ID, with event history. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # List return cases for a tenant, with optional filters. ``` GET /api/tenants/:tenantSlug/returns ``` List return cases for a tenant, with optional filters. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Update the status of a return via the returns provider, then update local mirror. Valid target statuses: complete, open, flagged, rejected, deleted. ``` PUT /api/tenants/:tenantSlug/returns/:returnId/status ``` Update the status of a return via the returns provider, then update local mirror. Valid target statuses: complete, open, flagged, rejected, deleted. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Attach an install the merchant approved on Shopify to this tenant. The install ran OAuth before the merchant signed in (App Store requirement 2.3.2), so the callback could not know the workspace and parked the grant under a claim token. The token is single use and expires after Edge.API.Shopify.ShopifyOAuthStart.ClaimTtl. A claim that is refused for a reason the merchant can fix (the workspace already holds another store, or another business holds this one) is put back for the rest of its lifetime, so the merchant can fix it and retry without installing again. ``` POST /api/tenants/:tenantSlug/shopify/connections/claim ``` Attach an install the merchant approved on Shopify to this tenant. The install ran OAuth before the merchant signed in (App Store requirement 2.3.2), so the callback could not know the workspace and parked the grant under a claim token. The token is single use and expires after Edge.API.Shopify.ShopifyOAuthStart.ClaimTtl. A claim that is refused for a reason the merchant can fix (the workspace already holds another store, or another business holds this one) is put back for the rest of its lifetime, so the merchant can fix it and retry without installing again. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Connect a Shopify store to a tenant using OAuth 2.0 client credentials. Exchanges client ID + secret for an access token, validates via GraphQL shop query, stores encrypted credentials, and registers webhooks. ``` POST /api/tenants/:tenantSlug/shopify/connections ``` Connect a Shopify store to a tenant using OAuth 2.0 client credentials. Exchanges client ID + secret for an access token, validates via GraphQL shop query, stores encrypted credentials, and registers webhooks. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Disconnect a Shopify store from a tenant ``` DELETE /api/tenants/:tenantSlug/shopify/connections ``` Disconnect a Shopify store from a tenant ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Get the current Shopify connection for a tenant ``` GET /api/tenants/:tenantSlug/shopify/connections ``` Get the current Shopify connection for a tenant ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # The consent URL for the store this tenant already holds, for a reconnect after Shopify stopped accepting its token. Only the stored shop is ever used: the tenant cannot name another store here, and the caller must be allowed to manage this tenant's integrations. This replaces the anonymous /api/shopify/oauth/authorize, which took any tenant slug and any shop from anyone. ``` GET /api/tenants/:tenantSlug/shopify/connections/reauthorize ``` The consent URL for the store this tenant already holds, for a reconnect after Shopify stopped accepting its token. Only the stored shop is ever used: the tenant cannot name another store here, and the caller must be allowed to manage this tenant's integrations. This replaces the anonymous /api/shopify/oauth/authorize, which took any tenant slug and any shop from anyone. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Current inbound texting settings for a tenant. ``` GET /api/tenants/:tenantSlug/sms-settings ``` Current inbound texting settings for a tenant. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Update inbound texting settings for a tenant. A field you omit keeps its stored value; an empty conversation slug clears it. ``` PUT /api/tenants/:tenantSlug/sms-settings ``` Update inbound texting settings for a tenant. A field you omit keeps its stored value; an empty conversation slug clears it. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # SmsTemplates\_Create ``` POST /api/tenants/:tenantSlug/sms-templates ``` SmsTemplates\_Create ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # SmsTemplates\_Delete ``` DELETE /api/tenants/:tenantSlug/sms-templates/:id ``` SmsTemplates\_Delete ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # SmsTemplates\_Get ``` GET /api/tenants/:tenantSlug/sms-templates/:id ``` SmsTemplates\_Get ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # SmsTemplates\_List ``` GET /api/tenants/:tenantSlug/sms-templates ``` SmsTemplates\_List ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Render a template with sample variables. ``` POST /api/tenants/:tenantSlug/sms-templates/:id/preview ``` Render a template with sample variables. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # SmsTemplates\_Update ``` PUT /api/tenants/:tenantSlug/sms-templates/:id ``` SmsTemplates\_Update ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # List connections visible to this tenant: its own linked connection plus unclaimed connections available for linking. Response item shape matches the admin listing so the portal component is URL-swap compatible. ``` GET /api/tenants/:tenantSlug/square/connections ``` List connections visible to this tenant: its own linked connection plus unclaimed connections available for linking. Response item shape matches the admin listing so the portal component is URL-swap compatible. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Get locations for a merchant connection this tenant may see. ``` GET /api/tenants/:tenantSlug/square/connections/:merchantId/locations ``` Get locations for a merchant connection this tenant may see. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Link an unclaimed Square connection to this tenant. ``` POST /api/tenants/:tenantSlug/square/connections/:merchantId/link ``` Link an unclaimed Square connection to this tenant. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Unlink this tenant's Square connection. ``` POST /api/tenants/:tenantSlug/square/connections/:merchantId/unlink ``` Unlink this tenant's Square connection. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantBlueprints\_ApplyGenerationRun ``` POST /api/tenants/:tenantSlug/blueprints/generate/:runId/apply ``` TenantBlueprints\_ApplyGenerationRun ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Delete a never-published draft blueprint (#354). Published blueprints return 409. ``` DELETE /api/tenants/:tenantSlug/blueprints/:slug ``` Delete a never-published draft blueprint (#354). Published blueprints return 409. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantBlueprints\_GenerateRecipe ``` POST /api/tenants/:tenantSlug/blueprints/generate ``` TenantBlueprints\_GenerateRecipe ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantBlueprints\_Get ``` GET /api/tenants/:tenantSlug/blueprints/:slug ``` TenantBlueprints\_Get ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantBlueprints\_GetGenerationRun ``` GET /api/tenants/:tenantSlug/blueprints/generate/:runId ``` TenantBlueprints\_GetGenerationRun ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantBlueprints\_List ``` GET /api/tenants/:tenantSlug/blueprints ``` TenantBlueprints\_List ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantBlueprints\_ListGenerationRuns ``` GET /api/tenants/:tenantSlug/blueprints/generate ``` TenantBlueprints\_ListGenerationRuns ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantBlueprints\_PreviewCompose ``` POST /api/tenants/:tenantSlug/blueprints/:slug/preview-compose ``` TenantBlueprints\_PreviewCompose ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantBlueprints\_Publish ``` POST /api/tenants/:tenantSlug/blueprints/:slug/publish ``` TenantBlueprints\_Publish ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantBlueprints\_Update ``` PUT /api/tenants/:tenantSlug/blueprints/:slug ``` TenantBlueprints\_Update ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantBlueprints\_Versions ``` GET /api/tenants/:tenantSlug/blueprints/:slug/versions ``` TenantBlueprints\_Versions ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # P2-A: what changed between two of the tenant's versions of this skill, field by field with the old and new values. \`to\` is a version number or \`draft\`. ``` GET /api/tenants/:tenantSlug/capability-flows/:capabilityName/versions/:from/diff/:to ``` P2-A: what changed between two of the tenant's versions of this skill, field by field with the old and new values. `to` is a version number or `draft`. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # #1046 Phase 2: constrained node-graph generation. Writes nothing to CapabilityFlows — a success returns the proposal for the editor to load as unsaved dirty state; a failed run returns 422 with the last attempt and its violations. Publish (with its hard gate) remains the only door to going live. ``` POST /api/tenants/:tenantSlug/capability-flows/:capabilityName/generate ``` \#1046 Phase 2: constrained node-graph generation. Writes nothing to CapabilityFlows — a success returns the proposal for the editor to load as unsaved dirty state; a failed run returns 422 with the last attempt and its violations. Publish (with its hard gate) remains the only door to going live. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantCapabilityFlows\_Get ``` GET /api/tenants/:tenantSlug/capability-flows/:capabilityName ``` TenantCapabilityFlows\_Get ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantCapabilityFlows\_List ``` GET /api/tenants/:tenantSlug/capability-flows ``` TenantCapabilityFlows\_List ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # #1046 Phase 2: the composed node universe of the tenant blueprint referencing this capability. The server-side twin of the portal's composedNodeIds util, which reconstructs from summaries and misses non-entry nodes in sibling capabilities. ``` GET /api/tenants/:tenantSlug/capability-flows/:capabilityName/node-scope ``` \#1046 Phase 2: the composed node universe of the tenant blueprint referencing this capability. The server-side twin of the portal's composedNodeIds util, which reconstructs from summaries and misses non-entry nodes in sibling capabilities. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantCapabilityFlows\_Publish ``` POST /api/tenants/:tenantSlug/capability-flows/:capabilityName/publish ``` TenantCapabilityFlows\_Publish ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # #2433: forget the tenant's own copy of this skill so customers hear the standard version again. Deletes every tenant-scoped row for the capability, published history included, then recomposes. P2-A: the rows are copied to CapabilityFlowSnapshots first, so History can restore them. ``` POST /api/tenants/:tenantSlug/capability-flows/:capabilityName/reset ``` \#2433: forget the tenant's own copy of this skill so customers hear the standard version again. Deletes every tenant-scoped row for the capability, published history included, then recomposes. P2-A: the rows are copied to CapabilityFlowSnapshots first, so History can restore them. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # P2-A: restore a set-aside copy as a draft. Never publishes. ``` POST /api/tenants/:tenantSlug/capability-flows/:capabilityName/snapshots/:snapshotId/restore ``` P2-A: restore a set-aside copy as a draft. Never publishes. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # P2-A: copy a published version into the draft. Never publishes; the merchant publishes the restored draft like any other edit. ``` POST /api/tenants/:tenantSlug/capability-flows/:capabilityName/versions/:version/restore ``` P2-A: copy a published version into the draft. Never publishes; the merchant publishes the restored draft like any other edit. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # P2-A: the copies Reset set aside, newest first. ``` GET /api/tenants/:tenantSlug/capability-flows/:capabilityName/snapshots ``` P2-A: the copies Reset set aside, newest first. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantCapabilityFlows\_Update ``` PUT /api/tenants/:tenantSlug/capability-flows/:capabilityName ``` TenantCapabilityFlows\_Update ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # #2433: merge the template's changes since this fork's base version into the tenant draft. Conflicts keep the merchant's value and are named. ``` POST /api/tenants/:tenantSlug/capability-flows/:capabilityName/update-from-template ``` \#2433: merge the template's changes since this fork's base version into the tenant draft. Conflicts keep the merchant's value and are named. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantCapabilityFlows\_Versions ``` GET /api/tenants/:tenantSlug/capability-flows/:capabilityName/versions ``` TenantCapabilityFlows\_Versions ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Register a new custom email domain with Resend. Returns DNS records to configure. ``` POST /api/tenants/:tenantSlug/email-domains ``` Register a new custom email domain with Resend. Returns DNS records to configure. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Get a domain's details including DNS records the tenant needs to configure. ``` GET /api/tenants/:tenantSlug/email-domains/:id ``` Get a domain's details including DNS records the tenant needs to configure. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # List all custom email domains for this tenant. ``` GET /api/tenants/:tenantSlug/email-domains ``` List all custom email domains for this tenant. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Remove a custom domain. ``` DELETE /api/tenants/:tenantSlug/email-domains/:id ``` Remove a custom domain. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Trigger domain verification after DNS records have been configured. ``` POST /api/tenants/:tenantSlug/email-domains/:id/verify ``` Trigger domain verification after DNS records have been configured. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantFaqCrawl\_AddConsent ``` POST /api/tenants/:tenantSlug/faq-crawl/consents ``` TenantFaqCrawl\_AddConsent ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Approve, reject, reopen or delete a selection in one call. The review queue is a bulk-select table, so doing this row by row would fire one request, one cache eviction and one corpus refresh per row. ``` POST /api/tenants/:tenantSlug/faq-crawl/entries/bulk ``` Approve, reject, reopen or delete a selection in one call. The review queue is a bulk-select table, so doing this row by row would fire one request, one cache eviction and one corpus refresh per row. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Queue a crawl and return immediately. This used to run the whole pipeline inline, which meant the merchant stared at a disabled button for minutes and lost every result if the six-minute HttpClient timeout fired. FaqCrawlWorkerService picks the run up; the portal polls GET runs/{id} for the progress bar. ``` POST /api/tenants/:tenantSlug/faq-crawl/consents/:id/crawl ``` Queue a crawl and return immediately. This used to run the whole pipeline inline, which meant the merchant stared at a disabled button for minutes and lost every result if the six-minute HttpClient timeout fired. FaqCrawlWorkerService picks the run up; the portal polls GET runs/{id} for the progress bar. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Add one FAQ by hand. It lands approved by default: the merchant wrote it, so there is nothing to review. No consent is attached, which is what migration 406 made possible. ``` POST /api/tenants/:tenantSlug/faq-crawl/entries ``` Add one FAQ by hand. It lands approved by default: the merchant wrote it, so there is nothing to review. No consent is attached, which is what migration 406 made possible. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantFaqCrawl\_DeleteEntry ``` DELETE /api/tenants/:tenantSlug/faq-crawl/entries/:id ``` TenantFaqCrawl\_DeleteEntry ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantFaqCrawl\_GetConsent ``` GET /api/tenants/:tenantSlug/faq-crawl/consents/:id ``` TenantFaqCrawl\_GetConsent ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantFaqCrawl\_GetRun ``` GET /api/tenants/:tenantSlug/faq-crawl/runs/:id ``` TenantFaqCrawl\_GetRun ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Import a CSV or JSON export. Partial success is the normal outcome and is reported row by row: a file with one bad line should not cost the merchant the other two hundred. ``` POST /api/tenants/:tenantSlug/faq-crawl/entries/import ``` Import a CSV or JSON export. Partial success is the normal outcome and is reported row by row: a file with one bad line should not cost the merchant the other two hundred. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantFaqCrawl\_ListConsents ``` GET /api/tenants/:tenantSlug/faq-crawl/consents ``` TenantFaqCrawl\_ListConsents ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # The review queue. Paged and searchable because a crawl of a real help centre returns hundreds of rows, and scoped by consent because a tenant with two registered domains was previously shown the same tenant-wide list under both. ``` GET /api/tenants/:tenantSlug/faq-crawl/entries ``` The review queue. Paged and searchable because a crawl of a real help centre returns hundreds of rows, and scoped by consent because a tenant with two registered domains was previously shown the same tenant-wide list under both. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantFaqCrawl\_ListRuns ``` GET /api/tenants/:tenantSlug/faq-crawl/runs ``` TenantFaqCrawl\_ListRuns ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantFaqCrawl\_RevokeConsent ``` DELETE /api/tenants/:tenantSlug/faq-crawl/consents/:id ``` TenantFaqCrawl\_RevokeConsent ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantFaqCrawl\_UpdateEntry ``` PATCH /api/tenants/:tenantSlug/faq-crawl/entries/:id ``` TenantFaqCrawl\_UpdateEntry ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantLiveStatus\_Get ``` GET /api/tenants/:tenantSlug/live-status ``` TenantLiveStatus\_Get ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Submit a phone number provisioning request for this tenant. Idempotent on the \`Idempotency-Key\` header: a replay of the same key in this environment returns the original row and does not notify again. Missing header is accepted; Edge mints a key the way the demo workspace request path does. Unique index \`ux\_PhoneNumberRequests\_IdempotencyKey\_Env\` is the race backstop. ``` POST /api/tenants/:tenantSlug/phone-number/request ``` Submit a phone number provisioning request for this tenant. Idempotent on the `Idempotency-Key` header: a replay of the same key in this environment returns the original row and does not notify again. Missing header is accepted; Edge mints a key the way the demo workspace request path does. Unique index `ux_PhoneNumberRequests_IdempotencyKey_Env` is the race backstop. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Get the most recent pending or provisioning phone number request for this tenant. ``` GET /api/tenants/:tenantSlug/phone-number/request ``` Get the most recent pending or provisioning phone number request for this tenant. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Get paginated SMS message log for this tenant. ``` GET /api/tenants/:tenantSlug/phone-number/messages ``` Get paginated SMS message log for this tenant. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Get the current phone number status for this tenant. Returns the assigned Twilio number with provisioning indicators. ``` GET /api/tenants/:tenantSlug/phone-number ``` Get the current phone number status for this tenant. Returns the assigned Twilio number with provisioning indicators. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Get SMS statistics for the tenant's phone number over the last N days. ``` GET /api/tenants/:tenantSlug/phone-number/sms-stats ``` Get SMS statistics for the tenant's phone number over the last N days. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantPolicyRules\_GetHandoff ``` GET /api/tenants/:tenantSlug/policy-rules/handoff ``` TenantPolicyRules\_GetHandoff ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantPolicyRules\_GetTone ``` GET /api/tenants/:tenantSlug/policy-rules/tone ``` TenantPolicyRules\_GetTone ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantPolicyRules\_GetVerification ``` GET /api/tenants/:tenantSlug/policy-rules/verification ``` TenantPolicyRules\_GetVerification ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantPolicyRules\_PutHandoff ``` PUT /api/tenants/:tenantSlug/policy-rules/handoff ``` TenantPolicyRules\_PutHandoff ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantPolicyRules\_PutTone ``` PUT /api/tenants/:tenantSlug/policy-rules/tone ``` TenantPolicyRules\_PutTone ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantPolicyRules\_PutVerification ``` PUT /api/tenants/:tenantSlug/policy-rules/verification ``` TenantPolicyRules\_PutVerification ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantShortLinkDomains\_Add ``` POST /api/tenants/:tenantSlug/shortlink-domains ``` TenantShortLinkDomains\_Add ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantShortLinkDomains\_Get ``` GET /api/tenants/:tenantSlug/shortlink-domains/:id ``` TenantShortLinkDomains\_Get ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantShortLinkDomains\_List ``` GET /api/tenants/:tenantSlug/shortlink-domains ``` TenantShortLinkDomains\_List ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantShortLinkDomains\_Remove ``` DELETE /api/tenants/:tenantSlug/shortlink-domains/:id ``` TenantShortLinkDomains\_Remove ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantShortLinkDomains\_Verify ``` POST /api/tenants/:tenantSlug/shortlink-domains/:id/verify ``` TenantShortLinkDomains\_Verify ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantSkillChecks\_Create ``` POST /api/tenants/:tenantSlug/capability-flows/:capabilityName/checks ``` TenantSkillChecks\_Create ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantSkillChecks\_Delete ``` DELETE /api/tenants/:tenantSlug/capability-flows/:capabilityName/checks/:checkId ``` TenantSkillChecks\_Delete ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantSkillChecks\_GetRun ``` GET /api/tenants/:tenantSlug/capability-flows/:capabilityName/checks/runs/:runId ``` TenantSkillChecks\_GetRun ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantSkillChecks\_List ``` GET /api/tenants/:tenantSlug/capability-flows/:capabilityName/checks ``` TenantSkillChecks\_List ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantSkillChecks\_SetActive ``` PUT /api/tenants/:tenantSlug/capability-flows/:capabilityName/checks/:checkId/active ``` TenantSkillChecks\_SetActive ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Queues a run of every active check against the saved draft. 202 with the run; an unfinished run is returned instead of a second one. ``` POST /api/tenants/:tenantSlug/capability-flows/:capabilityName/checks/runs ``` Queues a run of every active check against the saved draft. 202 with the run; an unfinished run is returned instead of a second one. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantSkillChecks\_Update ``` PUT /api/tenants/:tenantSlug/capability-flows/:capabilityName/checks/:checkId ``` TenantSkillChecks\_Update ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TenantWelcomeAudio\_Delete ``` DELETE /api/tenants/:tenantSlug/welcome-audio ``` TenantWelcomeAudio\_Delete ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 * 404 OK Not Found --- # TenantWelcomeAudio\_List ``` GET /api/tenants/:tenantSlug/welcome-audio ``` TenantWelcomeAudio\_List ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 * 404 OK Not Found --- # TenantWelcomeAudio\_Upload ``` POST /api/tenants/:tenantSlug/welcome-audio ``` TenantWelcomeAudio\_Upload ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 * 400 * 404 OK Bad Request Not Found --- # Whether this tenant's hard cases can reach a person (#1823, #1932). Read by the go-live checklist so a merchant finds out from us rather than from a customer who asked for a human and was told to go and find one. The same service answers the blueprint publish gate and the live-status card, so the explanation, the enforcement and the standing dashboard answer cannot drift apart. The payload carries the sentence and the page that fixes it; the portal renders, it does not decide. ``` GET /api/tenants/:tenantSlug/escalation-target ``` Whether this tenant's hard cases can reach a person (#1823, #1932). Read by the go-live checklist so a merchant finds out from us rather than from a customer who asked for a human and was told to go and find one. The same service answers the blueprint publish gate and the live-status card, so the explanation, the enforcement and the standing dashboard answer cannot drift apart. The payload carries the sentence and the page that fixes it; the portal renders, it does not decide. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Retrieves a specific tenant by its business slug. ``` GET /api/tenants/:tenantSlug ``` Retrieves a specific tenant by its business slug. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Returns the current backfill status for every language the tenant has recently triggered a backfill for. Empty list when no backfill has run in the last 24 hours. ``` GET /api/tenants/:tenantSlug/translation-backfill-status ``` Returns the current backfill status for every language the tenant has recently triggered a backfill for. Empty list when no backfill has run in the last 24 hours. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Updates only the tenant's language list, so the conversation editor can register a language the moment an author adds one to a node (#1030). Exactly one entry must be primary. Newly added non-primary languages trigger a translation backfill across the tenant's conversations; progress is available from the translation-backfill-status endpoint. ``` PUT /api/tenants/slug/:tenantSlug/languages ``` Updates only the tenant's language list, so the conversation editor can register a language the moment an author adds one to a node (#1030). Exactly one entry must be primary. Newly added non-primary languages trigger a translation backfill across the tenant's conversations; progress is available from the translation-backfill-status endpoint. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Updates the business-profile fields of your own tenant: display name, contact email, assistant name, business hours, escalation policy, phone and forwarding numbers, callback behaviour, and the email idle timeout. Requires the tenants.settings.manage permission. ``` PATCH /api/tenants/slug/:tenantSlug/profile ``` PATCH semantics: a field you omit keeps its stored value. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Tenants\_UpdateTenantTtsSettings ``` PUT /api/tenants/slug/:tenantSlug/tts-settings ``` Tenants\_UpdateTenantTtsSettings ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Connect Toast to a tenant. Validates credentials and stores encrypted. ``` POST /api/tenants/:tenantSlug/toast/connections ``` Connect Toast to a tenant. Validates credentials and stores encrypted. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Disconnect Toast from a tenant. ``` DELETE /api/tenants/:tenantSlug/toast/connections ``` Disconnect Toast from a tenant. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Get the current Toast connection for a tenant. ``` GET /api/tenants/:tenantSlug/toast/connections ``` Get the current Toast connection for a tenant. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Test the Toast connection by calling the Restaurants API. ``` POST /api/tenants/:tenantSlug/toast/connections/test ``` Test the Toast connection by calling the Restaurants API. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Connect Treez to a tenant. Validates the signing material against jwt-validation and stores the private key encrypted. ``` POST /api/tenants/:tenantSlug/treez/connections ``` Connect Treez to a tenant. Validates the signing material against jwt-validation and stores the private key encrypted. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Disconnect Treez from a tenant. ``` DELETE /api/tenants/:tenantSlug/treez/connections ``` Disconnect Treez from a tenant. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Get the current Treez connection for a tenant. ``` GET /api/tenants/:tenantSlug/treez/connections ``` Get the current Treez connection for a tenant. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # The callback URL the dispensary pastes into the Treez portal's webhook integration screen (Configurations > Config Page > Integration). Null when Pos:Treez:WebhookCallbackBaseUrl is unset or the tenant has no connection — the token itself never rides TreezConnectionInfo. ``` GET /api/tenants/:tenantSlug/treez/connections/webhook-url ``` The callback URL the dispensary pastes into the Treez portal's webhook integration screen (Configurations > Config Page > Integration). Null when Pos:Treez:WebhookCallbackBaseUrl is unset or the tenant has no connection — the token itself never rides TreezConnectionInfo. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Test the Treez connection by signing a JWT and calling jwt-validation. ``` POST /api/tenants/:tenantSlug/treez/connections/test ``` Test the Treez connection by signing a JWT and calling jwt-validation. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Returns the resolved default TTS voice configuration for a tenant. Used by the portal VoicePicker to show the inherited sector voice when no workspace voice is set. ``` GET /api/tts/:tenantSlug/default-voice ``` Returns the resolved default TTS voice configuration for a tenant. Used by the portal VoicePicker to show the inherited sector voice when no workspace voice is set. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 * 404 OK Not Found --- # Synthesizes speech for the given text using the tenant's configured TTS voice and settings. Language overrides are applied when available. ``` POST /api/tts/:tenantSlug/synthesize ``` Synthesizes speech for the given text using the tenant's configured TTS voice and settings. Language overrides are applied when available. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 * 400 * 403 * 404 OK Bad Request Forbidden Not Found --- # TtsVoices\_GetPreview ``` GET /api/tts/voices/:voiceId/preview ``` TtsVoices\_GetPreview ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # TtsVoices\_GetVoices ``` GET /api/tts/voices ``` TtsVoices\_GetVoices ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # ZammadConnection\_Connect ``` POST /api/tenants/:tenantSlug/zammad/connections ``` ZammadConnection\_Connect ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # ZammadConnection\_Disconnect ``` DELETE /api/tenants/:tenantSlug/zammad/connections ``` ZammadConnection\_Disconnect ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # ZammadConnection\_GetConnection ``` GET /api/tenants/:tenantSlug/zammad/connections ``` ZammadConnection\_GetConnection ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # ZammadConnection\_TestConnection ``` POST /api/tenants/:tenantSlug/zammad/connections/test ``` ZammadConnection\_TestConnection ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Connect Zendesk to a tenant. Encrypts and stores credentials, then registers the event-subscription webhook. ``` POST /api/tenants/:tenantSlug/zendesk/connections ``` Connect Zendesk to a tenant. Encrypts and stores credentials, then registers the event-subscription webhook. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Disconnect Zendesk from a tenant. Tears down the registered webhook first (best-effort, while credentials are still readable). ``` DELETE /api/tenants/:tenantSlug/zendesk/connections ``` Disconnect Zendesk from a tenant. Tears down the registered webhook first (best-effort, while credentials are still readable). ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Get the current Zendesk connection for a tenant. ``` GET /api/tenants/:tenantSlug/zendesk/connections ``` Get the current Zendesk connection for a tenant. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # List the tenant's Zendesk custom ticket fields (removable + active), so the portal can offer fact-key → field mappings without the merchant hand-copying field ids out of the Zendesk admin UI. ``` GET /api/tenants/:tenantSlug/zendesk/ticket-fields ``` List the tenant's Zendesk custom ticket fields (removable + active), so the portal can offer fact-key → field mappings without the merchant hand-copying field ids out of the Zendesk admin UI. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Test the Zendesk connection by calling the authenticated-user endpoint. ``` POST /api/tenants/:tenantSlug/zendesk/connections/test ``` Test the Zendesk connection by calling the authenticated-user endpoint. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Update the per-tenant Zendesk escalation settings (#1448): fact-key → custom-field mappings, default ticket priority, and default tags. ``` PUT /api/tenants/:tenantSlug/zendesk/connections/settings ``` Update the per-tenant Zendesk escalation settings (#1448): fact-key → custom-field mappings, default ticket priority, and default tags. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # ZohoDeskConnection\_Disconnect ``` DELETE /api/tenants/:tenantSlug/zoho-desk/connections ``` ZohoDeskConnection\_Disconnect ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # The tenant's connection, or { configured: false }. 'available' says whether this environment can connect Zoho Desk at all. ``` GET /api/tenants/:tenantSlug/zoho-desk/connections ``` The tenant's connection, or { configured: false }. "available" says whether this environment can connect Zoho Desk at all. ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # ZohoDeskConnection\_ListDepartments ``` GET /api/tenants/:tenantSlug/zoho-desk/connections/departments ``` ZohoDeskConnection\_ListDepartments ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # ZohoDeskConnection\_ListOrganizations ``` GET /api/tenants/:tenantSlug/zoho-desk/connections/organizations ``` ZohoDeskConnection\_ListOrganizations ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # ZohoDeskConnection\_SelectOrganization ``` POST /api/tenants/:tenantSlug/zoho-desk/connections/organization ``` ZohoDeskConnection\_SelectOrganization ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # ZohoDeskConnection\_TestConnection ``` POST /api/tenants/:tenantSlug/zoho-desk/connections/test ``` ZohoDeskConnection\_TestConnection ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # ZohoDeskConnection\_UpdateSettings ``` PUT /api/tenants/:tenantSlug/zoho-desk/connections/settings ``` ZohoDeskConnection\_UpdateSettings ## Request[​](#request "Direct link to request") ## Responses[​](#responses "Direct link to Responses") * 200 OK --- # Changelog ## 2026-10-07[​](#2026-10-07 "Direct link to 2026-10-07") * The platform is now Merrows. The base URLs in this reference are `https://api.merrows.ai` and `https://auth.merrows.ai/api/v1`, the portal is at `https://portal.merrows.ai`, and this site and its MCP server moved to `https://docs.merrows.ai`. The getringle.com hostnames still answer during the transition; point new integrations at the merrows.ai hosts. ## 2026-07-03[​](#2026-07-03 "Direct link to 2026-07-03") * Initial public release of docs.getringle.com: Edge API and Auth API references, getting-started guides, markdown and llms.txt outputs, and the hosted MCP server. * The Edge API now publishes a filtered public OpenAPI document (`consumer-v1`). The previous unversioned swagger document URL (`/swagger/v1/swagger.json`) was removed; public integrations should use `/swagger/consumer-v1/swagger.json` or the copy hosted on this site. --- # Authentication The Edge API accepts two kinds of credentials. Programmatic integrations use a tenant API key. Browser sessions and user-facing tools use a JWT issued by the Auth API. ## API keys (recommended for integrations)[​](#api-keys-recommended-for-integrations "Direct link to API keys (recommended for integrations)") Tenant API keys are prefixed `rgl_tenant_`. Send the key in the `X-Api-Key` header: ``` curl https://api.merrows.ai/api/tenants/{tenantSlug}/conversations \ -H "X-Api-Key: rgl_tenant_your_key_here" ``` API keys never go in the Authorization header `Authorization: Bearer ...` is reserved for JWTs. Sending an API key as a Bearer token returns 401. Always use the `X-Api-Key` header for API keys. ### Creating a key[​](#creating-a-key "Direct link to Creating a key") Create keys in the [portal](https://portal.merrows.ai) under your tenant's settings, or with an existing credential: ``` curl -X POST https://api.merrows.ai/api/tenants/{tenantSlug}/api-keys \ -H "X-Api-Key: rgl_tenant_existing_key" \ -H "Content-Type: application/json" \ -d '{"name": "my-integration"}' ``` The raw key is returned once at creation and stored hashed. If you lose it, revoke it and create a new one. A tenant key is scoped to its tenant. Requests against another tenant's resources return 403. ## JWT bearer tokens (user sessions)[​](#jwt-bearer-tokens-user-sessions "Direct link to JWT bearer tokens (user sessions)") The [Auth API](/api/auth/merrows-auth-api.md) issues JWTs on login: ``` curl -X POST https://auth.merrows.ai/api/v1/auth/login \ -H "Content-Type: application/json" \ -d '{"email": "you@example.com", "password": "..."}' ``` Send the resulting token on Edge API calls: ``` curl https://api.merrows.ai/api/tenants/{tenantSlug}/conversations \ -H "Authorization: Bearer eyJhbGciOi..." ``` Access tokens are short-lived. Use `POST /auth/refresh` with the refresh token to get a new one. Browsers on `*.merrows.ai` get the same JWT in an HttpOnly cookie at login, so requests from the Merrows subdomains authenticate automatically with `credentials: 'include'`. ## Permissions[​](#permissions "Direct link to Permissions") What a credential can do depends on its tenant role. Endpoints in this reference are annotated with the operations they allow. Endpoints for platform administration are not part of this public reference; they require a global admin session and are documented separately under [Internal API](/internal-api). --- # Channels A Merrows agent runs the same conversation definition across four channels. The engine adapts prompts and available actions per channel, and conversation authors can override behavior for a specific channel in the designer. ## Voice[​](#voice "Direct link to Voice") Customers call a phone number assigned to your tenant. Speech recognition, the conversation engine, and text-to-speech run in real time. The API surface you interact with covers phone number assignment (`/api/tenants/{tenantSlug}/phone-number`), outbound calls (`/api/tenants/{tenantSlug}/calls/outbound`), call analytics, transcripts, and per-conversation voice settings (TTS provider, voice, language). ## Chat[​](#chat "Direct link to Chat") Web chat embeds on your site or runs from the portal. Sessions survive page reloads and reconnects. Chat traffic flows over SignalR websockets rather than the REST endpoints in this reference, but conversation management, transcripts, and analytics for chat sessions are all here. ## SMS[​](#sms "Direct link to SMS") Customers text your tenant's number and the agent replies from the same number. SMS is opt-in per tenant and consent-aware: STOP, START, and HELP keywords are handled automatically, and outbound messages check stored consent. Templates live under `/api/tenants/{tenantSlug}/sms-templates`. ## Email[​](#email "Direct link to Email") Inbound email to your tenant's address starts or continues a threaded conversation. The agent replies in-thread. Email settings, templates, and per-thread conversation state are managed under the email endpoints (`/api/tenants/{tenantSlug}/email-settings`, `/api/tenants/{tenantSlug}/email-templates`, `/api/tenants/{tenantSlug}/email-conversations`). ## Where conversations come from[​](#where-conversations-come-from "Direct link to Where conversations come from") Conversations are designed in the [portal](https://portal.merrows.ai): a visual editor with versioning, per-channel prompts, and A/B experiments. The API reference covers reading and managing those definitions programmatically, running experiments, and pulling the resulting analytics. --- # Errors and rate limits The APIs use conventional HTTP status codes. Error bodies are JSON; the shape varies by endpoint but always includes a human-readable message. ## Status codes[​](#status-codes "Direct link to Status codes") | Code | Meaning | | ---- | -------------------------------------------------------------------------------------------------------------- | | 400 | The request body or parameters failed validation. The message says which field. | | 401 | No credential, an expired JWT, or an API key sent in the wrong header. | | 403 | Valid credential, but it lacks permission. Most often a tenant key used on another tenant's resources. | | 404 | The resource does not exist, or is outside your tenant's scope. | | 409 | The request conflicts with current state, for example activating a conversation version that no longer exists. | | 429 | Rate limited. Retry after a pause. | | 500 | Something failed on our side. Retry with backoff; contact support if it persists. | ## Common 401 causes[​](#common-401-causes "Direct link to Common 401 causes") * The API key was sent as `Authorization: Bearer ...`. Use the `X-Api-Key` header instead. * The JWT expired. Refresh it via `POST /auth/refresh` on the Auth API. * The key was revoked. ## Rate limits[​](#rate-limits "Direct link to Rate limits") Most endpoints are not rate limited. The exceptions protect paid upstream services and abuse-prone surfaces: * Text-to-speech synthesis (`POST /api/tts/...`) is limited per tenant. * A handful of anonymous endpoints have per-IP limits. A 429 response means you crossed one of these. Limits are windowed, so waiting briefly and retrying is the right client behavior. If your integration legitimately needs a higher TTS budget, contact support. --- # Your first request This walkthrough lists your tenant's conversations. You need your tenant slug (visible in the portal URL) and an API key ([how to create one](/getting-started/authentication.md)). ## Call the API[​](#call-the-api "Direct link to Call the API") ``` curl https://api.merrows.ai/api/tenants/{tenantSlug}/conversations \ -H "X-Api-Key: rgl_tenant_your_key_here" ``` A successful response is JSON with camelCase property names: ``` [ { "id": "7f6e5d4c-...", "slug": "support-active", "name": "Customer support", "version": 9, "isActive": true, "supportedLanguages": ["en-US", "es-MX"] } ] ``` ## Things to know[​](#things-to-know "Direct link to Things to know") * All request and response bodies are JSON. Responses use camelCase keys. * Route parameters like `{tenantSlug}` refer to your tenant's slug, not its display name. * A 401 means the credential is missing or invalid. A 403 means it is valid but scoped to a different tenant. See [Errors](/getting-started/errors.md). ## Where to go next[​](#where-to-go-next "Direct link to Where to go next") Browse the [Edge API reference](/api/edge/merrows-edge-api.md) for the full surface: transcripts, call analytics, experiments, outbound calls, templates, and integration connections. Each reference page has a runnable request panel and code samples. ---