Copiar página

Migrar de v2 a v3

La v3 es un re-ordenamiento, no una reescritura. Los mismos recursos y la misma lógica de negocio, con un contrato consistente encima. Tu misma API key funciona en ambas. La v2 sigue viva y congelada en /v2: migra a tu ritmo, endpoint por endpoint.

De un vistazo

Nueve cambios, todos mecánicos. Ninguno cambia qué hace la API, solo cómo la lees:

Áreav2v3
Base URL/v2/v3 (v2 sigue viva)
Casingsnake/camel mezcladocamelCase en todo
IDsUUID crudosPrefijados opacos (doc_, tmpl_…)
Errores{error:{code:E1xxx}}RFC 9457 problem+json
PaginaciónVarias formasUn envelope cursor unificado
EstadosMAYÚSCULAS_ESlowercase_en
HeadersSolo X-RateLimit-*Request-id, versión, rate limit IETF…
Status codesAlgunos malCorregidos (404 no 500…)
Webhookssnake_case + X-AllSign-SignatureCohorte v3: camelCase + Standard Webhooks (los clásicos no cambian)

Base URL

Cambia el prefijo de la ruta de /v2 a /v3. Eso es todo lo obligatorio para empezar: https://api.allsign.io/v3/.... La misma API key (allsign_live_sk_ / allsign_test_sk_) autentica en ambas versiones — no generes keys nuevas. La v2 no se apaga: está congelada (sin cambios de comportamiento) y puedes migrar un endpoint a la vez.

Casing

La v2 mezclaba snake_case y camelCase según el endpoint. La v3 es camelCase en todo — request y response, sin excepciones. Renombra tus claves: created_at → createdAt, signer_status → signerStatus, guest_link → guestLink.

IDs

Los UUID crudos se vuelven identificadores opacos con prefijo. Son cadenas opacas: no parsees su interior, solo guárdalas y reenvíalas. Un id malformado responde 400 INVALID_ID (antes de tocar la base de datos).

PrefijoRecurso
doc_Documento
sgr_Firmante (signer)
fie_Campo (field)
rol_Rol de un documento
tmpl_Plantilla
tv_Versión de plantilla
fld_Carpeta (folder)
ses_Sesión de firma
bat_Lote de envío masivo (bulk send)
sset_Signer set
cst_Constancia NOM-151
usr_Usuario
ten_Tenant
org_Organización
whe_Webhook endpoint
whd_Entrega de webhook
evt_Evento
whsec_Secreto de firma de webhook

Errores

El envelope propietario de v2 desaparece. La v3 usa RFC 9457 application/problem+json, con code en UPPER_SNAKE_CASE (estable) en vez del E1xxx numérico. Programa contra code, nunca contra el texto.

Antes (v2)

{
  "error": {
    "code": "E1300",
    "message": "document not found"
  }
}

Ahora (v3)

{
  "type": "https://allsign.io/developers/docs/errors#DOCUMENT_NOT_FOUND",
  "title": "Document not found",
  "status": 404,
  "detail": "No document exists with id doc_...",
  "code": "DOCUMENT_NOT_FOUND",
  "requestId": "req_..."
}

La validación semántica responde 422 con un arreglo errors[]: un objeto por campo con field y su pointer (JSON Pointer).

{
  "type": "https://allsign.io/developers/docs/errors#VALIDATION_ERROR",
  "title": "Validation failed",
  "status": 422,
  "code": "VALIDATION_ERROR",
  "errors": [
    { "field": "signers[0].email", "pointer": "/signers/0/email",
      "code": "INVALID_VALUE", "detail": "not a valid email address" }
  ]
}

Catálogo completo de códigos en Errores.

Paginación

Las varias formas de paginar de v2 se unifican en un solo envelope basado en cursor: los recursos vienen en data, con hasMore y nextCursor. Para la siguiente página, reenvía nextCursor como startingAfter hasta que hasMore sea false.

GET /v3/documents?limit=20&startingAfter=djF8Y3JlYXRlZEF0fC4uLg

{
  "object": "list",
  "data": [ { "id": "doc_..." }, { "id": "doc_..." } ],
  "hasMore": true,
  "nextCursor": "djF8Y3JlYXRlZEF0fC4uLg",
  "limit": 20
}

Estados

Los estados pasan de MAYÚSCULAS_ES (español) a lowercase_en (inglés). Actualiza tus comparaciones y tus mappings de UI:

v2v3
ESPERANDO_FIRMASawaiting_signatures
TODOS_FIRMARONcompleted
SELLOS_PDF / RECOLECTANDO_FIRMANTESdraft
ANULADOvoided

Recuerda que DocumentStatus y SignerStatus son x-extensible-enum: maneja valores nuevos sin romperte (ver Versionado).

Headers

La v3 agrega headers nuevos (en v2 solo existían los X-RateLimit-*). Vale la pena instrumentarlos:

HeaderPara qué
AllSign-Request-IdCorrelación: cítalo al reportar un problema (también en requestId del error).
AllSign-VersionLa versión fechada activa (ver Versionado).
RateLimit-*Límite, restante y reinicio (ver Rate limits).
Idempotency-Replayedtrue cuando una respuesta salió del caché de idempotencia, no de una ejecución nueva.

Los X-* de v2 no viajan en v3. Una respuesta v3 hecha con tu API key trae AllSign-Request-Id y RateLimit-*; ya no trae X-Allsign-Request-Id ni el trío X-RateLimit-*. Si tu cliente v2 leía esos headers, cámbialo al migrar. Los topes propios, como el de POST /v3/constancias, también responden con RateLimit-* y su 429 es problem+json RATE_LIMITED con Retry-After. Solo dos 429 conservan algún X-RateLimit-*: el del tope de invitaciones de POST /v3/documents/{id}/send (X-RateLimit-Reason: invite-fanout) y el tope diario por IP de una petición sin key válida, cuyo X-DailyRateLimit-Reset es un epoch (ver Rate limits). RateLimit-Reset es un delta en segundos: para saber cuánto esperar, lee solo Retry-After y los headers nuevos.

Status codes

Se corrigieron códigos que en v2 mentían. Si tu cliente v2 trataba un 500 como "reintenta", revisa estos:

  • templateId malformado → 400 INVALID_ID (antes 500).
  • GET /v3/users/me nunca responde 403: si tu key es válida, te ves a ti mismo.
  • Acceso cross-tenant (un id que no es tuyo) → 404, no 403: no revelamos que el recurso existe.

Webhooks

Migrar tus llamadas a /v3 no cambia tus webhooks. El formato de cada endpoint de webhook lo decide su propia versión de contrato (apiVersion), y hoy hay dos cohortes:

  • Tus destinos existentes son la cohorte clásica (v2legacy) y así se quedan: cuerpo snake_case congelado byte a byte, cabeceras X-AllSign-Event / X-AllSign-Event-Id / X-AllSign-Timestamp, y (con HMAC habilitado) la firma X-AllSign-Signature = HMAC-SHA256 en hex de "{timestamp}.{body}", con los bytes literales del secreto como llave.
  • Un endpoint creado con POST /v3/webhooks nace en la cohorte v3 (versión fechada 2026-07-11): sobre camelCase y firma Standard Webhooks (webhook-id / webhook-timestamp / webhook-signature) — la fórmula y la llave de verificación cambian, así que tu verificador clásico no sirve tal cual.
  • Uno creado desde el dashboard hereda el formato de tu cuenta: si ya tienes destinos clásicos, nace v2legacy (para no romper el handler que ya tienes); una cuenta que estrena integración nace en v3.
  • Cambiar un endpoint de cohorte hoy solo se puede desde el dashboard — PATCH /v3/webhooks/{id} no expone apiVersion.
  • Algunos eventos cambian de nombre entre cohortes (p.ej. signature.reminder_sent → signer.reminder_sent), y ambas cohortes traen la cabecera AllSign-Livemode — para la clásica es la única señal de entorno.

El detalle completo (tabla lado a lado, nacimiento y reintentos por cohorte) está en Webhooks → Las dos cohortes.

Checklist

Diez pasos para migrar sin sorpresas:

  1. Cambia la base URL de /v2 a /v3 (la misma API key sigue funcionando).
  2. Pasa todas tus claves a camelCase (request y response).
  3. Trata los IDs como cadenas opacas con prefijo; no parsees su interior.
  4. Reescribe el manejo de errores a problem+json; programa contra code.
  5. Lee errors[] (con pointer) en los 422 de validación.
  6. Adopta el envelope cursor: data + hasMore + nextCursor.
  7. Remapea los estados a lowercase_en y tolera valores nuevos en los enums extensibles.
  8. Instrumenta los headers nuevos (AllSign-Request-Id, RateLimit-*, Idempotency-Replayed) y deja de leer los X-* legacy (X-RateLimit-Reset es epoch, no delta).
  9. Ajusta tu manejo de status codes (404 en vez de 500; /users/me nunca 403; cross-tenant → 404).
  10. Decide la cohorte de tus webhooks: los destinos clásicos siguen en v2legacy; un endpoint nuevo por API nace v3 y se verifica con Standard Webhooks.