SuperAPI AI Directory

commercetools-intake

Agents & models

View repository

Updated 10-21 19:29

About this skill

Intake

Call Intake so a channel adapter can turn one unstructured request into one commercetools entity. The HTTP surface is a single stateless endpoint. Each call starts a fresh run and returns either a created entity or an error. It does not resume a previous run, so a follow-up email or ticket comment is not another turn of the same call.

The adapter owns three decisions Intake will not make: which entity to create, which Customer the message is for, and whether this inbound event is a new request or a reply to an entity already created.

Out of scope

  • Building or automating the Merchant Center Intake UI. Use that UI once, before writing the adapter, to confirm the same prompt creates the entity. The UI can ask a clarifying question. This endpoint cannot.
  • Connect connectors, transactional email, and CRM sync. Those belong to commercetools-integrations.
  • Quote negotiation after a Quote Request exists (Staged Quote, Quote, Order). That is the Quotes API.

Workflow

  1. Docs search (required, run first) — The first time you use this skill in a session you must run this before answering. It gathers the latest verified documentation as your primary grounding, filtered to the products this skill covers. Use this script for documentation search while working with this skill; the Knowledge MCP covers everything else. Always confirm details against retrieved documentation rather than the skill text alone:
node "<this skill's directory>/scripts/docs-search.mjs" \
  --query "Intake responses API Cart Quote Request Shopping List file upload" \
  --app-name "<host app: claude-code, claude-chat, cursor, codex, copilot — or the host's own name>" \
  --model "<current-model>" \
  --commercetools-project-key "<if known>" \
  --commercetools-region "<if known>" \
  --limit 10

Pass the commercetools project key and region (as in api.{region}.commercetools.com) only if already in your context; otherwise omit both. Never search files or ask the user for them.

  1. Fetch the REST schema before writing a request or parsing a response. Run:

    node scripts/openApi-schemata.mjs \
      --resource-name "api-AgentResponsesSuccess" \
      --app-name "<host app: claude-code, claude-chat, cursor, codex, copilot — or the host's own name>" \
      --model "<current-model>"
    

    The output is the OpenAPI specification for that resource. If the name is not recognized, the script prints valid names. Re-run with api-Cart-write, api-QuoteRequest, or api-ShoppingList when the follow-up is an update to the entity Intake created, not another Intake call.

  2. Confirm the Project can accept the call. Intake is enabled for the Project (otherwise FeatureDisabled). The API client has the manage_intake_agent:{projectKey} scope. Product Search is enabled (otherwise ProductSearchNotEnabled). The buyer already exists as a Customer. Intake looks a Customer up by email and does not create one.

  3. Run the same prompt in Merchant Center before writing the adapter. Paste the prompt and any file into Merchant Center Intake. A failure there is the Project, catalog, or Customer. A success there and a failure from the API is the request the integration sent. A success that needed a clarifying question does not count: the prompt that produced the entity is the prompt the API body must contain.

  4. Choose outputType. Read choose-output.md. The field is required. Intake never infers it from the message.

  5. Map the channel into one request. Read call-responses.md, then the channel file:

    • Mailbox: email.md
    • Zendesk: zendesk.md
    • Any other drop (a form, a drive folder, another helpdesk): the same mapping in call-responses.md. A new channel is a new normalizer, not a new Intake contract.
  6. Call once per new request, and remember that you did. The endpoint has no idempotency key. Conditionally insert the channel's own id (email Message-ID, Zendesk ticket id) with the normalized request as queued work, acknowledge the delivery, then mark the row as a call with an unknown outcome immediately before the POST. On success, store that id against threadId, entity.id, and, for a Quote Request, cartId. Recovery may send a queued row that was never marked. It must not resend a marked row. A second POST creates a second entity.

  7. Handle the outcome and write it back using handle-outcome.md. A 201 can still carry warnings. A 400 names what was missing. Do not answer a 400 by calling again with the same body.

  8. Route a later message on the same thread by the stored outcome. An entity already stored is updated with the normal Cart, Quote Request, or Shopping List APIs. A confirmed no-write failure (a 400 that created nothing) allows one corrected Intake attempt when the reply supplies the missing input. A pending queued row, a call with an unknown outcome, or a partial creation (QuoteRequestCreationFailed with cartId) is resolved from that stored state. Do not POST again to finish it.

Checklist

  • The same prompt created the entity in Merchant Center before the adapter was written. A clarifying question in that UI does not count
  • outputType was chosen by the integration, not left for Intake to guess
  • The prompt states the buyer's email, and for a Cart or Quote Request a shipping country, in plain text
  • A Shopping List name is stated in the prompt or a file. Intake does not invent one
  • businessUnit and store are passed as resource identifiers when the channel knows them
  • Uploads use the files part, at most 3 files, only allowed content types
  • The channel event id and the normalized request are stored as queued work before the webhook is acknowledged. A call is marked as an unknown outcome immediately before the POST, then stored against entity.id and threadId. Recovery sends unstarted work and does not resend a call that may have completed
  • Warnings and the specific 400 code are written back to the channel
  • A follow-up on the same email thread or ticket follows the stored outcome: update an existing entity, allow one corrected Intake attempt after a confirmed no-write failure when the reply supplies the missing input, and resolve a pending, unknown, or partial-creation outcome without a blind retry