Authentication
Create named API keys in Settings > Connections > API keys. Select only the scopes required by the integration. The raw key is displayed once, so store it in a secret manager when it is created.
Use the key as a bearer token:
curl https://portal.heyx.app/public-api/publicapi.v1.Workspace/Me \ -H "Authorization: Bearer <your-workspace-api-key>" \ -H "Content-Type: application/json" \ -d '{}'You can also send X-API-Key, but Authorization: Bearer is preferred.
Scopes
Section titled “Scopes”Scopes have the same exact meaning for public Connect endpoints and Workspace MCP tools. Operations that list more than one scope require all of them.
| Scope | Operations |
|---|---|
me:read | Me |
customer:read | GetCustomer, SearchCustomers, LookupCustomersByIdentifier; also required for PrepareWorkOrder |
customer:create | CreateCustomer |
customer:write | PatchCustomer |
customer_datafield:write | PatchCustomerDataFields |
customer_file:create | Create and complete document or photo uploads |
customer_file:read | List and download-link document or photo records; also required when creating a comment with attachments |
customer_comment:create | CreateCustomerComment |
customer_comment:read | ListCustomerComments, ListCustomerCommentHistory |
customer_activity:read | ListCustomerTimelineEvents |
customer_event:create | CreateCustomerEvent |
datafield:read | ListDataFields |
correspondence:create | AddCorrespondenceMessage |
advanced_task:read | ListAdvancedTaskInstances |
advanced_task:update | UpdateAdvancedTaskInstance |
advanced_task:attach | AttachAdvancedTask |
problem:read | ListProblems, GetProblem, SearchProblems |
problem:create | CreateProblem |
problem:update | UpdateProblem, UpdateProblemStatus |
problem:comment | AddProblemComment |
work_order:read | ListWorkOrders, GetWorkOrder, SearchWorkOrders; PrepareWorkOrder also requires customer:read |
work_order:create | CreateWorkOrder |
work_order:update | UpdateWorkOrder |
work_order:complete | CompleteWorkOrder |
work_order:cancel | CancelWorkOrder |
catalog:read | ListProducts, ListDiscounts, SearchProducts, GetProduct |
catalog:write | CreateProduct, UpdateProduct |
quote:read | GetQuote, ListQuotes |
quote:create | CreateQuote |
quote:update | UpdateQuote, DiscardQuote |
quote:confirm | ConfirmQuote |
order:read | GetOrder, ListOrders, GetOrderCancellationImpact |
order:cancel | CancelOrder |
payment:read | GetPayment, ListPayments, ListRefunds |
payment:create | CreatePayment |
payment:update | RecordManualPayment |
payment:refund | CreateRefund |
invoice:create | CreateInvoice |
invoice:read | GetInvoice, ListInvoices, ListAccountingConnections |
invoice:send | SendInvoice |
proforma:read | GetProForma, ListProFormas |
proforma:create | CreateProForma |
appointment:create | CreateAppointment |
appointment:read | GetAppointment, ListAppointments, ListCustomerAppointments, ListAvailableAppointmentSlots, ListAgendas, ListAppointmentTypes, ListAgendaEligibleMembers, ListAppointmentResultCodes |
appointment:update | UpdateAppointment |
appointment:cancel | CancelAppointment |
appointment:record_result | RecordAppointmentResult |
action_request:create | CreateManualActionRequest |
member:read | ListMembers, GetMember, SearchMembers, ListMemberInvitations |
member_roles:update | ReplaceMemberRoles |
role:read | ListRoles, GetRole, SearchRoles |
team:read | ListTeams, GetTeam, SearchTeams |
team:create | CreateTeam |
member:invite | EmailMemberInvitation |
member_invite_link:create | CreateInviteLink |
problem_template:read | ListProblemTemplates, GetProblemTemplate |
problem_template:create | CreateProblemTemplate |
work_order_template:read | ListWorkOrderTemplates, GetWorkOrderTemplate, ListWorkOrderTemplateLocationFields |
work_order_template:create | CreateWorkOrderTemplate |
work_order_template:update | UpdateWorkOrderTemplate |
work_order_template:archive | ArchiveWorkOrderTemplate |
inventory:read | SearchInventoryLocations, ListInventoryBalances, ListInventoryMovements, GetInventoryReceipt, GetOrderInventorySummary, ListOrderReservations, ListOrderStockDemand, LookupProductIdentifier, ListProductIdentifiers, ListInventoryTransfers, ListInventoryBackorders |
inventory_location:create | CreateInventoryLocation |
inventory:adjust | AdjustInventory |
inventory:move | MoveInventory |
inventory_receipt:create | CreateInventoryReceipt |
inventory_receipt:update | AddInventoryReceiptLine only; not general receipt editing |
inventory_receipt:post | ReceiveInventory |
inventory:reserve | AllocateOrderStock, CreateOrderReservation, ReleaseReservation |
inventory:consume | ConsumeReservation |
inventory:return | ReturnInventory |
inventory_identifier:write | AddProductIdentifier, DeleteProductIdentifier |
inventory:transfer | StartInventoryTransfer, CompleteInventoryTransfer |
inventory_backorder:write | CreateInventoryBackorder, UpdateInventoryBackorderEta |
team:update | UpdateTeam |
team_member:add | AddTeamMember |
team_member:remove | RemoveTeamMember |
role:create | CreateRole |
role:update | UpdateRole |
member_invitation:revoke | RevokeMemberInvitation |
email_template:read | ListEmailTemplates, GetEmailTemplate |
email_template:create | CreateEmailTemplate (unpublished plain-text draft) |
document_template:read | ListDocumentTemplates, GetDocumentTemplate |
document_template:create | CreateDocumentTemplate (blank PDF draft) |
advanced_task_definition:read | ListAdvancedTaskDefinitions, GetAdvancedTaskDefinition |
workflow_automation:read | ListWorkflowAutomations, GetWorkflowAutomation |
journey:read | ListJourneyConfig |
journey:write | SetCustomerJourneyStatus, ClearCustomerJourneyStatus |
contact:read | GetContact, ListContacts |
contact:create | CreateContact |
contact:write | UpdateContact |
API keys are creator-bound. Requests use the creating account’s current workspace membership, resource authorization, and delegation rights in addition to the key scopes. A scope cannot grant access the creator does not have.
Create separate named keys for separate clients or duties so each can be expired, restricted, or revoked independently.
Actor permissions
Section titled “Actor permissions”CreateProblem and CreateWorkOrder use the same creation scopes for both
general/direct and template-backed requests. Template discovery and authoring
have separate scopes. Inventory receipt creation, adding lines, and posting
also have separate scopes: only posting changes stock.
Actor permissions are separate from API-key scopes. Search requires the corresponding workspace read permission and applicable resource access. Product search accepts settings or inventory read access. Problem-template discovery uses content-template read access; work-order-template discovery accepts content-template or settings read access. Both template authoring operations require settings write access. Work-order preparation also requires readable customer data and only returns populated locations in the current Customer View. Problem/work-order creation needs the corresponding write capability and customer write access when linked to a customer. Both template-backed creation paths additionally require content-template read access, independently of discovery.
ContentTemplate email/document/advanced-task-definition reads require settings read access, not merely operational content-template access. Email and document draft creation requires settings write access. Neither scope grants draft editing, publication, sending, or document generation.
Directory role grants are administrative, not effective Customer View claims. Delegation checks apply to both existing and requested grants; system/owner role updates and removal of the last owner remain protected. See Manage Roles.
Use the exact scopes exposed in API-key settings and the tools advertised by
tools/list. Wildcard access does not implicitly expose
MCP tools. Missing credentials, missing exact scopes, disabled MCP, and denied
resource IDs are distinct diagnostic cases; the Bruno collection includes them.
IP restrictions
Section titled “IP restrictions”API keys can be restricted to specific IP addresses or CIDR ranges. If a key has no allowed CIDRs, it can be used from any IP.
Timeouts
Section titled “Timeouts”If HeyX cannot start processing a request within 30 seconds, it returns a retryable timeout response. If processing has already started but the HTTP request times out, the operation may still continue in the background. Never assume a timeout cancelled a mutation, and do not blindly retry non-idempotent operations.