---
title: "Create a customer-support ticket"
method: POST
path: "/api/v1/support/ticket"
tags: ["Support"]
---

# Create a customer-support ticket

`POST /api/v1/support/ticket`

Public write exception for customer support. Authentication is optional, but the boolean `accept_privacy=true` is mandatory and is persisted as the purpose-bound audit event `privacy_accepted` / `privacy_policy_v1`. The submitted contact details, message, client IP and a user-agent capped by the runtime are stored in the account database solely to process, audit and protect the support request; ticket contents are never public or available to the public MCP. Related context accepts only a validated company slug and a local or canonical-origin OpenMercantil URL, which is stored as text and never dereferenced. The JSON body is capped at 32 KiB.

## Request body

- SupportTicketCreateRequest — Customer-supplied support content. Privacy consent is purpose-bound to handling and protecting this request; it is not marketing consent.
  - `email` string, email, required
  - `name` string — Trimmed before persistence; ASCII control characters are rejected.
  - `category` 'comercial' | 'tecnico' | 'datos' | 'rgpd' | 'partnerships' | 'sugerencia' | 'bug' | 'otro', required — Stable support-routing category accepted by the current account schema.
  - `subject` string, required — Trimmed before length validation; ASCII control characters are rejected.
  - `body` string, required — Trimmed before length validation. TAB, CR and LF are permitted; other ASCII control characters are rejected.
  - `related_company_slug` string — Optional validated context; it does not establish identity or ownership.
  - `related_url` string — Optional context restricted at runtime to a single-slash absolute same-origin path or an HTTPS URL on exactly openmercantil.es, without userinfo, port, backslash or control characters. Query and fragment are removed before persistence. The URL is stored as text and never dereferenced.
  - `accept_privacy` true, required — Strict purpose-bound acceptance, persisted as privacy_accepted/privacy_policy_v1; never interpreted as marketing consent.

## Response `201`

Ticket created; only its internal numeric id and non-secret public reference are returned

- SupportTicketCreatedResponse
  - `ok` true, required
  - `ticket_id` integer, required
  - `public_id` string, required

## Other responses

- `400` — Invalid JSON fields, validation failure or missing strict privacy consent
- `413` — Request body exceeds 32 KiB
- `429` — API plan quota exhausted or the per-IP ceiling of 5 ticket creations per hour was reached
- `503` — The account database or migrated support schema is unavailable; creation fails closed

---

[API](https://skmtc.net/openmercantil/apis/openmercantil-public-api.md) · [All operations](https://skmtc.net/openmercantil/apis/openmercantil-public-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/openmercantil/openmercantil-public-api/revisions/996f96a11758/schema)
