---
name: hexagon-setup
description: Set up a customer's Hexagon product with a scoped API key. Check subscriptions, configure WhatsApp Sales, and guide secure hosted billing.
---

# Set up Hexagon

Use this skill when the customer wants to configure Hexagon. Keep their chosen product and
workspace. Milo uses a subscription. Sales may use accepted outcome terms or an
existing prepaid agreement; read the account’s actual billing mode. This is not a generic model API or a spending card.
Normal visual setup remains at https://joinhexagon.com/start; this skill is an optional way to get help from an agent.

Read the current contract before making requests:
- Discovery: https://joinhexagon.com/.well-known/hexagon-commerce
- OpenAPI: https://api.joinhexagon.com/api/v1/agent-commerce/openapi.json
- Human setup and key issuance: https://joinhexagon.com/start/developer

The customer chooses the product at the guided setup page and creates an `hx_agent_` key:
- Milo uses a personal key, tied to the person and their existing Milo account/history.
- WhatsApp Sales uses a key for one selected company workspace and selected products.

Use it only
as `Authorization: Bearer` with `https://api.joinhexagon.com/api/v1/agent-commerce`. Read it
from `HEXAGON_API_KEY` in the customer's secure environment; never ask them to paste it in chat,
put it in client-side code or URLs, or display it in logs. Legacy `hx_live_` data keys and internal
service credentials cannot replace this key. Every request checks the key’s current authority. Workspace-owned keys act as their creator while
they remain an owner/admin, otherwise as the workspace’s current owner. Revocation, disabling,
expiry or no remaining owner stops access. A Milo key needs no company workspace.

## Read the chosen product

Read `/products/{product}` (`products:read`) and, when granted, `/billing/{product}`
(`billing:read`). Use `milo` or `sales_v3` exactly. Follow the returned links for
missing human steps. For a new Brazilian Sales number, `phoneBusinessVerification` reports only
status and an owner setup link. The owner uploads business documents and explicitly submits
carrier verification there; keys cannot read private fields/comments or submit it. Carrier approval
does not purchase a number or authorize Meta. Keep subscription billing separate from Sales billing. Never treat an old prepaid balance as proof that an outcome plan is active.

## Milo subscription

- For Milo, `linked:false` means the customer must open the returned `connectUrl` and complete
  normal sign-in/linking. Re-read afterwards. Do not create a substitute account or workspace;
  an existing account may need proof of its current Milo session to preserve its history.
- For an existing Milo subscription (`subscriptionInForce:true`), use the returned `billingUrl`.
  The canonical checkout checks provider subscription state and returns management instead of a
  duplicate purchase when a subscription is already in force.
- When the customer wants a subscription and grants `checkout:create`, prepare `/checkouts`
  using their chosen plan and the exact product-specific request in OpenAPI. Preserve the request's
  UUID `requestKey` and selection on retry. Do not invent prices: the canonical hosted page confirms
  the current terms before the customer pays.
- Show the returned human link. `manage_subscription` or `included_access` is a management
  destination, not a completed purchase. `customer_checkout` still needs customer completion.
  A missing Milo link (409 `milo_link_required`) returns to the product-read/linking step.
  `company_covered` (409, or `companyCovered:true` on the read) means their company already pays for
  their Milo: do not sell a plan. `coverage_unreadable` (or `companyCovered:null`) means ask again later.
  A `checkout_reconciliation_required` answer means the unresolved attempt needs reconciliation;
  do not mint a new request to conceal it. Re-read billing after the customer finishes.
- Product configuration beyond these reads and subscription links stays in Milo.
  `setup:write` and `products:activate` do not apply to the subscription product.

## Configure Sales

1. Follow the returned owner action for missing human steps. A saved card is not funded prepaid credit; an outcome plan is ready only after its accepted terms and card mandate are verified.
2. With `setup:write`, read `/products/{product}/setup`, then configure drafts using the operations
   documented in OpenAPI. Use the returned `setup.version` as `expectedVersion`. Send only
   supported fields; workspace and actor come from the key, never the request body.
3. For instructions, use the customer's reviewed business policy and `reviewed:true` only when
   it has actually been reviewed. Do not invent store facts, permissions, refund policies or
   approval.
4. Shopify and Meta/WhatsApp provider authorization remain in the human setup page. Do not
   request provider secrets or attempt to replace an existing merchant connection.
5. Activate only when the customer has authorized activation, the key has `products:activate`,
   and current requirements are ready. An activation-only key reads `version` from product status
   (`products:read`), uses it as `expectedVersion`, and refreshes that same status on 409; it does
   not need `setup:write`. Activation starts real automations billed under the workspace’s accepted agreement. Saving a draft or a card does not activate anything. Pause and retry also require this
   scope; retry may finish an already-requested activation.
6. Re-read readiness after a change. `operationPending:true` means unconfirmed, not completed.
   Retry the saved version when appropriate. On a version conflict, reload and reconcile the
   customer's intended change. Never start a new payment, provider setup or activation to hide
   an uncertain result. Respect `Retry-After` for 429 responses.

## Billing boundary

Read `/billing/{product}` for the accepted mode, terms, card readiness and owner action. New
outcome acceptance and secure card setup happen in the returned Hexagon billing page with a
live owner session, then hosted Stripe. Show that owner link and resume by reading billing;
do not call enrollment or payment endpoints with the agent key. Existing prepaid agreements
remain separate. Use the offer returned now, not prices remembered from this skill.

Milo keeps its own subscription billing. `checkout:create` prepares an unpaid hosted
link; it does not approve pricing or payment. Keys cannot submit card credentials, accept a
tariff, enable refill or change subscriptions. Authorized automations can incur charges under
already accepted terms. Never collect raw card numbers or security codes.

### Existing prepaid credit agreements

Automatic reload is on by default for Sales credits. Until the workspace has reload set up
(including while an earlier reload checkout is still open: billing replaces it with this purchase),
`POST /checkouts` returns `credit_checkout_with_reload`: a billing link where the customer sees
the purchase with reload on (the returned wallet-currency threshold and amount, no monthly limit by default) and ticks
one consent before paying. Show it as is; send `autoReload:false` only when the customer asked
for a one-time purchase, which returns the plain hosted `credit_topup` link. Keep the same UUID
`requestKey` when you retry or re-check: once the customer paid from the link, the same request
answers with its `topup` and `paymentCompleted:true`; do not ask them to pay again. If it says
`amountChanged:true`, the customer paid `topup.amountMinor` instead of what you asked; report that
amount. `purchaseEnded:true` (`nextStep:"retry_with_new_request_key"`) means it ended unpaid: use a
new `requestKey` for a new attempt.

For prepaid Sales, balance and usage describe the workspace billing account, not a key’s budget.
Do not prepare another top-up for an outcome plan or use it to bypass a stopped plan.
