> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Asistente de registro 10DLC con borradores de guardar y reanudar

> Registre su marca y campaña TCR a través del asistente de Orbit: guarde borradores parciales entre sesiones, verifique el teléfono de un propietario único por OTP, ejecute el preflight sobre el borrador guardado y envíe de forma atómica.

# Asistente de registro 10DLC

El asistente es la forma recomendada de completar el [registro de marca y campaña TCR](/guides/10dlc-registration). Convierte el flujo lineal de un solo disparo en un proceso guiado y reanudable:

* **Guarde y reanude** — su borrador persiste entre sesiones, pestañas y semanas. Cierre la pestaña o vuelva mañana; retome donde lo dejó.
* **Muévase entre pasos de forma no lineal** — el asistente sigue `brand`, `campaign` y `review` como pasos independientes. Complete las muestras de la campaña mientras la sección de marca todavía está incompleta, y la carga útil de progreso mantiene ambos conteos.
* **Valide antes de pagar** — la validación por campo se dispara en cada guardado, y una pasada de lint previa al envío puntúa el borrador guardado contra los patrones de rechazo conocidos de TCR antes de que se cobre la tarifa de registro upstream.

<Note>
  El asistente escribe únicamente en el almacenamiento de borradores de su propia organización. No retiene, intercepta ni enruta ningún tráfico de mensajes.
</Note>

Todos los endpoints del asistente viven bajo `/api/v1/compliance/10dlc/wizard`. Autentíquese con su clave API, exactamente igual que para los [endpoints de marca y campaña](/guides/10dlc-registration).

## Roles y límites de tasa

* Lecturas (`GET /wizard`, `GET /wizard/draft`) — cualquier rol autenticado de la organización.
* Escrituras (`PUT /wizard/draft`, `DELETE /wizard/draft`, `POST /wizard/phone/send`, `POST /wizard/phone/confirm`, `POST /wizard/preflight`, `POST /wizard/submit`) — rol de propietario o administrador.
* Perfil de escritura: 10 peticiones por minuto, igual que los endpoints heredados de marca/campaña. Preflight del asistente: 30 peticiones por minuto, igual que el endpoint de preflight ad-hoc.

***

## GET `/10dlc/wizard` — carga útil de progreso

Devuelve el objeto de progreso calculado que el panel usa para su banner "Continúe donde lo dejó". Siempre `200 OK` — una organización nueva obtiene la forma de borrador vacío con `state: "not_started"`.

```bash theme={null}
curl https://api.orbit.devotel.io/api/v1/compliance/10dlc/wizard \
  -H "X-API-Key: dv_live_sk_your_key_here"
```

**Respuesta:**

```json theme={null}
{
  "data": {
    "state": "in_progress",
    "current_step": "campaign",
    "brand": {
      "completed_fields": 10,
      "total_fields": 10,
      "missing_fields": []
    },
    "campaign": {
      "completed_fields": 4,
      "total_fields": 6,
      "missing_fields": ["message_flow", "optout_message"]
    },
    "next_action": "fill_campaign"
  },
  "meta": {
    "request_id": "req_wiz001",
    "timestamp": "2026-09-02T10:00:00Z"
  }
}
```

`state` es uno de `not_started`, `in_progress`, `brand_pending`, `campaign_pending`, `ready`, `rejected`. `current_step` es `brand`, `campaign` o `review`. `next_action` es una pista legible por máquina: `fill_brand`, `fill_campaign`, `review_and_submit`, `amend_brand`, `amend_campaign` o `done`. Cuando la marca o la campaña ya se enviaron, la respuesta también lleva `brand_id`, `campaign_id` y cualquier motivo de rechazo upstream.

`GET /10dlc/wizard/draft` devuelve el borrador completo guardado (campos de marca, campos de campaña, paso actual) para prerrellenar el formulario.

***

## PUT `/10dlc/wizard/draft` — guardado parcial

Guarda cualquier subconjunto de campos de marca y/o campaña. Cada campo es opcional — solo se validan los campos que envía, y el resto conserva sus valores guardados anteriormente. `current_step` se actualiza por separado de modo que una reanudación aterrice en la pantalla correcta.

```bash theme={null}
curl -X PUT https://api.orbit.devotel.io/api/v1/compliance/10dlc/wizard/draft \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "brand": {
      "entity_type": "PRIVATE_PROFIT",
      "display_name": "Acme Corp",
      "company_name": "Acme Corporation Inc.",
      "email": "compliance@acme.com"
    },
    "current_step": "brand"
  }'
```

Un guardado que falla la validación devuelve `422` y deja el borrador persistido intacto — el estado guardado anteriormente sobrevive.

**Campos de marca:** `entity_type`, `display_name`, `company_name`, `ein`, `phone`, `street`, `city`, `state`, `postal_code`, `country`, `email`, `website`, `vertical`.

**Campos de campaña:** `usecase`, `description` (40–4096 caracteres), `sample_message` (1–10 mensajes), `message_flow` (mín. 40 caracteres), `help_message` (mín. 20), `optout_message` (mín. 20), `is_political`, `cv_token`.

<Tip>
  Guarde tras cada campo obligatorio si lo desea — cada guardado cuesta menos de un token de tasa de escritura y el borrador es la red de seguridad. El `brand_id` de la campaña nunca se teclea a mano: el asistente lo rellena a partir del resultado del envío de la marca.
</Tip>

***

## Verificación del teléfono del propietario único (OTP)

Las marcas de EE. UU. con `entity_type: "SOLE_PROPRIETOR"`, y solo esas, sustituyen un número de móvil verificado por un EIN: TCR ancla la identidad del propietario único en un número de teléfono que el registrante demuestra que controla. Cualquier otro tipo de entidad de EE. UU. debe enviar un EIN en su lugar.

Verifique el número antes de enviar:

```bash theme={null}
# 1. Envíe el desafío al brand.phone del borrador
curl -X POST https://api.orbit.devotel.io/api/v1/compliance/10dlc/wizard/phone/send \
  -H "X-API-Key: dv_live_sk_your_key_here"
```

**Respuesta:**

```json theme={null}
{
  "data": {
    "verification_id": "vf_abc123",
    "status": "pending",
    "channel": "sms",
    "expires_at": "2026-09-02T10:10:00Z"
  },
  "meta": {
    "request_id": "req_wiz002",
    "timestamp": "2026-09-02T10:00:00Z"
  }
}
```

```bash theme={null}
# 2. Confirme el código del SMS
curl -X POST https://api.orbit.devotel.io/api/v1/compliance/10dlc/wizard/phone/confirm \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"code": "483921"}'
```

**Respuesta:**

```json theme={null}
{
  "data": {
    "status": "verified",
    "phone": "+14155551234",
    "verified_at": "2026-09-02T10:04:12Z"
  },
  "meta": {
    "request_id": "req_wiz003",
    "timestamp": "2026-09-02T10:04:12Z"
  }
}
```

La prueba está vinculada a la cadena exacta de teléfono guardada en el borrador. Si edita `brand.phone` después de verificar, la prueba antigua deja de contar y el envío falla con `422` hasta que ejecute un nuevo desafío contra el nuevo número. Llamar a `/phone/send` sobre un número ya verificado devuelve `409 ALREADY_VERIFIED`; llamar a `/phone/confirm` sin un desafío pendiente devuelve `404`.

***

## POST `/10dlc/wizard/preflight` — lint del borrador guardado

Puntúa el **borrador del asistente persistido** contra el catálogo de patrones de rechazo conocidos de TCR, de modo que la pantalla "Revisar y enviar" ve los hallazgos sobre el borrador exacto que está a punto de enviar — sin posibilidad de la deriva de lint que tiene el [endpoint de preflight](/guides/10dlc-registration#preflight-your-submission) ad-hoc cuando analiza una carga útil construida a mano.

El cuerpo de la petición es opcional: `expected_msg_per_day_per_number` (para la regla de nivel de rendimiento) y `brand_vetting_score` (0–100) cuando ya posea uno.

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/compliance/10dlc/wizard/preflight \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{}'
```

La forma de la respuesta — `score`, `verdict`, `findings[]` — es idéntica a la del [linter de preflight en la página de registro](/guides/10dlc-registration#what-the-10dlc-linter-checks). Como con ese endpoint, un veredicto `pass` significa "ningún patrón de rechazo conocido coincidió", no "TCR aprobará".

***

## POST `/10dlc/wizard/submit` — marca + campaña atómicas

Valida el borrador completo y luego envía la marca y la campaña en una sola llamada. La verificación de la marca suele completarse en 1–48 horas; la campaña sigue inmediatamente después.

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/compliance/10dlc/wizard/submit \
  -H "X-API-Key: dv_live_sk_your_key_here"
```

**Respuesta (`201 Created`):**

```json theme={null}
{
  "data": {
    "state": "brand_pending",
    "current_step": "review",
    "brand_id": "BXXXXXX",
    "campaign_id": "CXXXXXX",
    "next_action": "done"
  },
  "meta": {
    "request_id": "req_wiz004",
    "timestamp": "2026-09-02T10:05:00Z"
  }
}
```

Los fallos de validación devuelven `422` antes de que se cobre nada, con `details.section` indicándole si los campos faltantes o no válidos están en la sección `brand` o `campaign`.

**Semántica de fallos — la guarda atómica:**

* **Marca rechazada upstream** — no se envía ninguna campaña. El borrador se conserva con el motivo de rechazo de la marca estampado, y `next_action` cambia a `amend_brand`. Corrija los campos de la marca y vuelva a enviar.
* **Campaña rechazada upstream** — el `brand_id` aceptado se persiste, el estado permanece en `brand_pending` y el motivo de rechazo de la campaña se estampa. Un reenvío se salta por completo la etapa de marca, de modo que la tarifa de la marca nunca se vuelve a cobrar; solo la campaña vuelve a pagar.
* **5xx upstream o proveedor no disponible** — el borrador se conserva literalmente y puede reintentarlo tal cual.

El estado transita a `ready` una vez que tanto la marca como la campaña vuelven como `APPROVED` de la revisión del operador.

***

## DELETE `/10dlc/wizard/draft` — restablecer

```bash theme={null}
curl -X DELETE https://api.orbit.devotel.io/api/v1/compliance/10dlc/wizard/draft \
  -H "X-API-Key: dv_live_sk_your_key_here"
```

Devuelve `204 No Content`. Restablece el asistente al borrador vacío (`state: "not_started"`). Esto **no** borra los identificadores de marca o campaña aprobados que constan en el archivo — solo restablece el estado de trabajo del asistente, de modo que es seguro como limpieza posterior a la aprobación o como un "empezar de nuevo".

***

## Orden completo del ciclo de vida

1. `PUT /10dlc/wizard/draft` — complete progresivamente la marca + la campaña.
2. `(solo SOLE_PROPRIETOR)` `POST /10dlc/wizard/phone/send` → `POST /10dlc/wizard/phone/confirm`.
3. `POST /10dlc/wizard/preflight` — corrija los hallazgos hasta que el veredicto pase.
4. `POST /10dlc/wizard/submit` — envío atómico.
5. `GET /10dlc/wizard` — sondee el estado hasta `ready` (o `GET /10dlc/campaigns/:id/status` para el mapa por operador, como en la [página de registro](/guides/10dlc-registration#step-3-wait-for-approval)).
6. `DELETE /10dlc/wizard/draft` — limpieza opcional posterior a la aprobación.

<Warning>
  Los endpoints heredados de un solo disparo (`POST /10dlc/brand`, `POST /10dlc/campaign`) siguen disponibles para pipelines programados. El asistente es el flujo de operador recomendado; los endpoints directos exigen una carga útil completamente poblada en una sola petición.
</Warning>
