---
title: "Constancias — Endpoints API v3 de AllSign"
type: reference
canonical_url: "https://allsign.io/developers/docs/endpoints/constancias"
api_version: "2026-07-11"
---

# Constancias

Los ejemplos usan `$ALLSIGN_API_KEY`. Defínela una vez con tu key de sandbox: `export ALLSIGN_API_KEY="allsign_test_sk_…"` (en PowerShell: `$env:ALLSIGN_API_KEY="allsign_test_sk_…"`).

[Descargar OpenAPI](https://allsign.io/developers/docs/openapi.public.json)[Colección de Postman](https://allsign.io/developers/docs/allsign-api-v3.postman_collection.json)

Endpoints

-   [POST`/constancias`](#emitir-constancia-nom-151)
-   [GET`/constancias/{constancia_id}`](#recuperar-una-constancia)
-   [GET`/constancias`](#listar-constancias)
-   [POST`/constancias/verify`](#verificar-una-constancia)
-   [GET`/constancias/certchain`](#raiz-de-confianza-para-verificar-offline)

## El objeto ConstanciaResponse

#### Atributos

-   `livemode` boolean requerido
    
    `true` en entorno `live`, `false` en `test`/`dev` (marca de agua, sin validez legal).
    
-   `id` string requerido
    
-   `hashSha256` string requerido
    
-   `externalId` string requerido puede ser null
    
-   `label` string requerido puede ser null
    
-   `constancia` string requerido
    
-   `constanciaEncoding` string, siempre "base64"
    
-   `constanciaMediaType` string
    
    default "application/pkcs7-mime"
    
-   `constanciaSha256` string requerido
    
-   `serialNumber` string requerido puede ser null
    
-   `algorithm` string requerido puede ser null
    
-   `issuer` string requerido puede ser null
    
-   `sealedAt` string (fecha-hora ISO 8601) requerido puede ser null
    
-   `policyOid` string requerido puede ser null
    
-   `tsaName` string requerido puede ser null
    
-   `environment` string requerido
    
-   `sandbox` boolean requerido
    
-   `downloadUrl` string requerido
    
-   `downloadUrlExpiresAt` string (fecha-hora ISO 8601) requerido
    
-   `createdAt` string (fecha-hora ISO 8601) requerido
    

**El objeto ConstanciaResponse**

```
{
  "livemode": false,
  "id": "cst_83c44d9ca7c7479cb88bd7b09c08f6ff",
  "hashSha256": "683cd72903d1381092c59cb519b999124fdd04954fcafb37cb1207f6bfba9e01",
  "externalId": null,
  "label": "v3audit-ejemplos factura F-1024",
  "constancia": "<base64 de contrato.pdf>",
  "constanciaEncoding": "base64",
  "constanciaMediaType": "application/pkcs7-mime",
  "constanciaSha256": "714d26194f9cdaac8a55724ccf914a7ef5d524a4c0a761c13b5d606132d3660d",
  "serialNumber": "SANDBOX-CB59CC05CBAA4902",
  "algorithm": "sha-256",
  "issuer": "AllSign Sandbox — NOM-151 Mock (no validez legal)",
  "sealedAt": "2026-07-11T18:00:00Z",
  "policyOid": null,
  "tsaName": "AllSign Sandbox — NOM-151 Mock (no validez legal)",
  "environment": "test",
  "sandbox": true,
  "downloadUrl": "<url-firmada>",
  "downloadUrlExpiresAt": "2026-07-11T18:15:01.274000Z",
  "createdAt": "2026-07-11T18:00:00.325000Z"
}
```

Grabado en el entorno interno de AllSign con una key de sandbox · backend `24c0469` · 8 oct 2026, 06:12 (hora CDMX) · test `docs-checks-v3/tests/ejemplos/constancias.ejemplos.spec.ts`

## Emitir constancia NOM-151

POST `/constancias`

Emite una **Constancia de Conservación NOM-151** a partir del hash SHA-256 de tu documento. **Tu documento nunca sale de tu infraestructura.** No es una restricción nuestra: la NOM-151-SCFI-2016 lo **ordena**. Apéndice Normativo A, numeral A.2.4 — *«el Prestador de Servicios de Certificación únicamente recibirá la huella digital electrónica del mensaje de datos»*. Usa este endpoint si ya firmas por tu cuenta (e.firma del SAT, tu propio flujo) y solo necesitas la prueba legal del momento en que el documento existió. **El hash** va en hexadecimal minúsculas de 64 caracteres — exactamente lo que produce `sha256sum archivo.pdf`. Se aceptan mayúsculas y se normalizan; **no** se acepta base64 ni prefijos tipo `sha256:`. **`Idempotency-Key` es obligatoria.** Este endpoint cobra y llama a un PSC externo: sin la key, un timeout de red te deja sin forma segura de reintentar. Reintentar con la misma key devuelve la primera respuesta, nunca emite dos veces. **`externalId`** es tu propia referencia (el folio de tu expediente). Te sirve para recuperar la constancia después sin haber guardado nuestro `id`, y como segunda red contra el doble cobro. Reusar un `externalId` **con el mismo hash** devuelve la constancia ya emitida; reusarlo **con otro hash** devuelve `409` — la referencia ya está tomada por otro documento, y devolverte la constancia equivocada sería peor que fallar. **Facturación y entornos.** En `live` consume créditos y llama al PSC. Con una API key `test` o `dev` no cobra, no contacta al PSC y devuelve un artefacto **sin validez legal**, marcado con `sandbox: true` y `livemode: false`. **Requiere contrato.** El addon se activa por tenant tras firmar el contrato de prestación de servicio; sin él, `live` responde `403 CONTRACT_REQUIRED`.

#### Parámetros

-   `Idempotency-Key` string header requerido
    
    Clave única (UUID v4) que vuelve idempotente el POST: un reintento con la misma clave repite la respuesta original en lugar de volver a crear, cobrar o notificar.
    
-   `AllSign-Version` enum header
    
    Fecha del contrato contra la que quieres resolver la petición. Si la omites se sirve la versión vigente; una fecha desconocida responde 400 `UNSUPPORTED_API_VERSION`.
    
    Valores: `2026-07-11`
    

#### Cuerpo de la petición

application/json

-   `hashSha256` string requerido
    
    SHA-256 hex del documento.
    
    de 64 a 64 caracteres
    
-   `externalId` string puede ser null
    
    máx. 255 caracteres
    
-   `label` string puede ser null
    
    máx. 255 caracteres
    

#### Devuelve

**201** Constancia emitida. El artefacto viene **inline en base64** en `constancia`. — [el objeto ConstanciaResponse](#objeto-constanciaresponse)

Errores posibles (problem+json): [400](https://allsign.io/developers/docs/errors) [401](https://allsign.io/developers/docs/errors) [402](https://allsign.io/developers/docs/errors) [403](https://allsign.io/developers/docs/errors) [409](https://allsign.io/developers/docs/errors) [422](https://allsign.io/developers/docs/errors) [429](https://allsign.io/developers/docs/errors) [503](https://allsign.io/developers/docs/errors)

**cURL**

```
curl -X POST 'https://api.allsign.io/v3/constancias' \
  -H "Authorization: Bearer $ALLSIGN_API_KEY" \
  -H "AllSign-Version: 2026-07-11" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "hashSha256": "683cd72903d1381092c59cb519b999124fdd04954fcafb37cb1207f6bfba9e01",
  "label": "v3audit-ejemplos factura F-1024"
}'
```

**Node**

```
import { randomUUID } from 'node:crypto';

const respuesta = await fetch('https://api.allsign.io/v3/constancias', {
    method: 'POST',
    headers: {
        Authorization: `Bearer ${process.env.ALLSIGN_API_KEY}`,
        'AllSign-Version': '2026-07-11',
        'Idempotency-Key': randomUUID(),
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({
        hashSha256: '683cd72903d1381092c59cb519b999124fdd04954fcafb37cb1207f6bfba9e01',
        label: 'v3audit-ejemplos factura F-1024',
    }),
});
console.log(respuesta.status, await respuesta.json());
```

**Python**

```
import os
import uuid

import requests

respuesta = requests.post(
    "https://api.allsign.io/v3/constancias",
    headers={
        "Authorization": f"Bearer {os.environ['ALLSIGN_API_KEY']}",
        "AllSign-Version": "2026-07-11",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "hashSha256": "683cd72903d1381092c59cb519b999124fdd04954fcafb37cb1207f6bfba9e01",
        "label": "v3audit-ejemplos factura F-1024",
    },
)
print(respuesta.status_code, respuesta.json())
```

**Respuesta · 201**

```
{
  "livemode": false,
  "id": "cst_83c44d9ca7c7479cb88bd7b09c08f6ff",
  "hashSha256": "683cd72903d1381092c59cb519b999124fdd04954fcafb37cb1207f6bfba9e01",
  "externalId": null,
  "label": "v3audit-ejemplos factura F-1024",
  "constancia": "<base64 de contrato.pdf>",
  "constanciaEncoding": "base64",
  "constanciaMediaType": "application/pkcs7-mime",
  "constanciaSha256": "714d26194f9cdaac8a55724ccf914a7ef5d524a4c0a761c13b5d606132d3660d",
  "serialNumber": "SANDBOX-CB59CC05CBAA4902",
  "algorithm": "sha-256",
  "issuer": "AllSign Sandbox — NOM-151 Mock (no validez legal)",
  "sealedAt": "2026-07-11T18:00:00Z",
  "policyOid": null,
  "tsaName": "AllSign Sandbox — NOM-151 Mock (no validez legal)",
  "environment": "test",
  "sandbox": true,
  "downloadUrl": "<url-firmada>",
  "downloadUrlExpiresAt": "2026-07-11T18:15:00.856000Z",
  "createdAt": "2026-07-11T18:00:00.325000Z"
}
```

**Respuesta · 409 · EXTERNAL_ID_CONFLICT**

```
{
  "type": "https://allsign.io/developers/docs/errors#EXTERNAL_ID_CONFLICT",
  "title": "Conflict",
  "status": 409,
  "detail": "externalId 'pedido-muzi0on9' already identifies a constancia for another document (hash 1872a4d06486…). Use a different externalId, or send the same hash to retrieve the one already issued.",
  "instance": "/v3/constancias",
  "code": "EXTERNAL_ID_CONFLICT",
  "requestId": "req_0d782805b9534c43bd20d8468e9b3ce2"
}
```

Grabado en el entorno interno de AllSign con una key de sandbox · backend `24c0469` · 8 oct 2026, 06:12 (hora CDMX) · test `docs-checks-v3/tests/ejemplos/constancias.ejemplos.spec.ts`

## Recuperar una constancia

GET `/constancias/{constancia_id}`

Devuelve una constancia que emitimos, con el **artefacto inline en base64** — así que basta con haber guardado el `id` (o tu `externalId`) para recuperarla meses después. **Archiva `constancia`, no `downloadUrl`.** La URL de descarga es una conveniencia con caducidad (`downloadUrlExpiresAt`); si guardas el JSON con la URL y vuelves después, te queda un enlace muerto. El base64 es la fuente de verdad y no expira. Los campos `sealedAt`, `serialNumber`, `policyOid` y `tsaName` se extraen **del interior del token**, donde están cubiertos por la firma — no del JSON que envuelve la respuesta del PSC. `sealedAt` es el `genTime` del sello: el instante con valor legal. Con `Accept: application/pkcs7-mime` la misma ruta devuelve el **DER crudo** en vez del JSON, listo para pasárselo a `openssl` sin decodificar nada.

#### Parámetros

-   `constancia_id` string ruta requerido
    
-   `AllSign-Version` enum header
    
    Fecha del contrato contra la que quieres resolver la petición. Si la omites se sirve la versión vigente; una fecha desconocida responde 400 `UNSUPPORTED_API_VERSION`.
    
    Valores: `2026-07-11`
    

#### Devuelve

**200** La constancia, con el artefacto inline. — [el objeto ConstanciaResponse](#objeto-constanciaresponse)

Errores posibles (problem+json): [400](https://allsign.io/developers/docs/errors) [401](https://allsign.io/developers/docs/errors) [403](https://allsign.io/developers/docs/errors) [404](https://allsign.io/developers/docs/errors) [422](https://allsign.io/developers/docs/errors) [429](https://allsign.io/developers/docs/errors)

**cURL**

```
curl 'https://api.allsign.io/v3/constancias/cst_83c44d9ca7c7479cb88bd7b09c08f6ff' \
  -H "Authorization: Bearer $ALLSIGN_API_KEY" \
  -H "AllSign-Version: 2026-07-11"
```

**Node**

```
const respuesta = await fetch('https://api.allsign.io/v3/constancias/cst_83c44d9ca7c7479cb88bd7b09c08f6ff', {
    headers: {
        Authorization: `Bearer ${process.env.ALLSIGN_API_KEY}`,
        'AllSign-Version': '2026-07-11',
    },
});
console.log(respuesta.status, await respuesta.json());
```

**Python**

```
import os

import requests

respuesta = requests.get(
    "https://api.allsign.io/v3/constancias/cst_83c44d9ca7c7479cb88bd7b09c08f6ff",
    headers={
        "Authorization": f"Bearer {os.environ['ALLSIGN_API_KEY']}",
        "AllSign-Version": "2026-07-11",
    },
)
print(respuesta.status_code, respuesta.json())
```

**Respuesta · 200**

```
{
  "livemode": false,
  "id": "cst_83c44d9ca7c7479cb88bd7b09c08f6ff",
  "hashSha256": "683cd72903d1381092c59cb519b999124fdd04954fcafb37cb1207f6bfba9e01",
  "externalId": null,
  "label": "v3audit-ejemplos factura F-1024",
  "constancia": "<base64 de contrato.pdf>",
  "constanciaEncoding": "base64",
  "constanciaMediaType": "application/pkcs7-mime",
  "constanciaSha256": "714d26194f9cdaac8a55724ccf914a7ef5d524a4c0a761c13b5d606132d3660d",
  "serialNumber": "SANDBOX-CB59CC05CBAA4902",
  "algorithm": "sha-256",
  "issuer": "AllSign Sandbox — NOM-151 Mock (no validez legal)",
  "sealedAt": "2026-07-11T18:00:00Z",
  "policyOid": null,
  "tsaName": "AllSign Sandbox — NOM-151 Mock (no validez legal)",
  "environment": "test",
  "sandbox": true,
  "downloadUrl": "<url-firmada>",
  "downloadUrlExpiresAt": "2026-07-11T18:15:01.274000Z",
  "createdAt": "2026-07-11T18:00:00.325000Z"
}
```

**Respuesta · 404 · CONSTANCIA_NOT_FOUND**

```
{
  "type": "https://allsign.io/developers/docs/errors#CONSTANCIA_NOT_FOUND",
  "title": "Not Found",
  "status": 404,
  "detail": "No constancia was found with that id.",
  "instance": "/v3/constancias/cst_6d09d152ab804645b8884b7e20337328",
  "code": "CONSTANCIA_NOT_FOUND",
  "requestId": "req_c8a10a1a99bb4db09e4d9b3a9f42a9ef"
}
```

Grabado en el entorno interno de AllSign con una key de sandbox · backend `24c0469` · 8 oct 2026, 06:12 (hora CDMX) · test `docs-checks-v3/tests/ejemplos/constancias.ejemplos.spec.ts`

## Listar constancias

GET `/constancias`

Lista las constancias del tenant, más recientes primero, con paginación por cursor. **El listado NO trae el artefacto.** Devolver el base64 de hasta 100 constancias por página significaría descargarlas todas de nuestro almacenamiento en cada petición. Para el artefacto usa `GET /v3/constancias/{constanciaId}`, que trae uno. Sirve para **conciliar**: filtra por tu `externalId` para encontrar el expediente que buscas, o pagina el periodo completo para cuadrar lo emitido contra lo cobrado. Paginación: manda `startingAfter` con el `nextCursor` de la respuesta anterior. `hasMore` te dice si vale la pena pedir otra página. El listado está **acotado al entorno de tu API key**: una key `test` no ve las constancias `live` del tenant, ni al revés.

#### Parámetros

-   `limit` integer query
    
    default 20 · entre 1 y 100
    
-   `startingAfter` string query
    
-   `externalId` string query
    
-   `AllSign-Version` enum header
    
    Fecha del contrato contra la que quieres resolver la petición. Si la omites se sirve la versión vigente; una fecha desconocida responde 400 `UNSUPPORTED_API_VERSION`.
    
    Valores: `2026-07-11`
    

#### Devuelve

**200** Página de constancias (sin el artefacto — ver la nota arriba).

Ver los 5 atributos de la respuesta

-   `object` string, siempre "list"
    
    Siempre `"list"`.
    
-   `data` array de objetos requerido
    
    Ver 14 atributos hijos
    
    -   `data[].livemode` boolean requerido
        
        `true` en entorno `live`, `false` en `test`/`dev` (marca de agua, sin validez legal).
        
    -   `data[].object` string, siempre "constancia"
        
        Siempre `"constancia"`.
        
    -   `data[].id` string requerido
        
    -   `data[].hashSha256` string requerido
        
    -   `data[].externalId` string puede ser null
        
    -   `data[].label` string puede ser null
        
    -   `data[].constanciaSha256` string puede ser null
        
    -   `data[].serialNumber` string puede ser null
        
    -   `data[].sealedAt` string (fecha-hora ISO 8601) puede ser null
        
    -   `data[].policyOid` string puede ser null
        
    -   `data[].tsaName` string puede ser null
        
    -   `data[].environment` string requerido
        
    -   `data[].sandbox` boolean requerido
        
    -   `data[].createdAt` string (fecha-hora ISO 8601) requerido
        
    
-   `hasMore` boolean requerido
    
-   `limit` integer requerido
    
-   `nextCursor` string puede ser null
    

Errores posibles (problem+json): [400](https://allsign.io/developers/docs/errors) [401](https://allsign.io/developers/docs/errors) [403](https://allsign.io/developers/docs/errors) [422](https://allsign.io/developers/docs/errors) [429](https://allsign.io/developers/docs/errors)

**cURL**

```
curl 'https://api.allsign.io/v3/constancias?limit=5' \
  -H "Authorization: Bearer $ALLSIGN_API_KEY" \
  -H "AllSign-Version: 2026-07-11"
```

**Node**

```
const respuesta = await fetch('https://api.allsign.io/v3/constancias?limit=5', {
    headers: {
        Authorization: `Bearer ${process.env.ALLSIGN_API_KEY}`,
        'AllSign-Version': '2026-07-11',
    },
});
console.log(respuesta.status, await respuesta.json());
```

**Python**

```
import os

import requests

respuesta = requests.get(
    "https://api.allsign.io/v3/constancias?limit=5",
    headers={
        "Authorization": f"Bearer {os.environ['ALLSIGN_API_KEY']}",
        "AllSign-Version": "2026-07-11",
    },
)
print(respuesta.status_code, respuesta.json())
```

**Respuesta · 200**

```
{
  "object": "list",
  "data": [
    {
      "livemode": false,
      "object": "constancia",
      "id": "cst_83c44d9ca7c7479cb88bd7b09c08f6ff",
      "hashSha256": "683cd72903d1381092c59cb519b999124fdd04954fcafb37cb1207f6bfba9e01",
      "externalId": null,
      "label": "v3audit-ejemplos factura F-1024",
      "constanciaSha256": "714d26194f9cdaac8a55724ccf914a7ef5d524a4c0a761c13b5d606132d3660d",
      "serialNumber": "SANDBOX-CB59CC05CBAA4902",
      "sealedAt": "2026-07-11T18:00:00Z",
      "policyOid": null,
      "tsaName": "AllSign Sandbox — NOM-151 Mock (no validez legal)",
      "environment": "test",
      "sandbox": true,
      "createdAt": "2026-07-11T18:00:00.325000Z"
    },
    {
      "livemode": false,
      "object": "constancia",
      "id": "cst_d664e0f6c9bc440086ca777d83ad4899",
      "hashSha256": "6f1aeb27eb4962aa1b5b41517b25cd44e4dd8548652b9a189db51c77860d3f9d",
      "externalId": "pedido-muzftkgx",
      "label": "v3audit-ejemplos constancia original",
      "constanciaSha256": "e0739e3838e175ea2c1c090dda289bdf075a04bfe8a745cf35254075b901bd7c",
      "serialNumber": "SANDBOX-BC87121081EF45BA",
      "sealedAt": "2026-07-11T17:00:34Z",
      "policyOid": null,
      "tsaName": "AllSign Sandbox — NOM-151 Mock (no validez legal)",
      "environment": "test",
      "sandbox": true,
      "createdAt": "2026-07-11T17:00:34.535000Z"
    },
    {
      "livemode": false,
      "object": "constancia",
      "id": "cst_9afc5eabbff2413fb9ebefc661c83efe",
      "hashSha256": "d768c518537eb60c11d8884bf3c2edbb72d97cf2178dcb49065e1d42ecdf4ad8",
      "externalId": null,
      "label": "v3audit-ejemplos factura F-1024",
      "constanciaSha256": "4ba5788195f551bfb27c17e8fa03e928df899cc06feb7edada1599b34efcef02",
      "serialNumber": "SANDBOX-BCA90D6F9CEB45A6",
      "sealedAt": "2026-07-11T16:58:23Z",
      "policyOid": null,
      "tsaName": "AllSign Sandbox — NOM-151 Mock (no validez legal)",
      "environment": "test",
      "sandbox": true,
      "createdAt": "2026-07-11T16:58:23.388000Z"
    },
    {
      "livemode": false,
      "object": "constancia",
      "id": "cst_5e0a125652304f61b856a903160fc992",
      "hashSha256": "5abbbac063ea69840f916cdeeaa1e8328b4c4b18943bcc17cf5bf40e4e5b0462",
      "externalId": "pedido-muzan15b",
      "label": "v3audit-ejemplos constancia original",
      "constanciaSha256": "6acb30589bbe70a794a4717630ffe085d0b8e1dbb9b864504b922e80de372fcd",
      "serialNumber": "SANDBOX-70E660CAB89A4ED8",
      "sealedAt": "2026-07-11T14:35:31Z",
      "policyOid": null,
      "tsaName": "AllSign Sandbox — NOM-151 Mock (no validez legal)",
      "environment": "test",
      "sandbox": true,
      "createdAt": "2026-07-11T14:35:31.330000Z"
    },
    {
      "livemode": false,
      "object": "constancia",
      "id": "cst_170be41c795b475b9ec34fcd09256129",
      "hashSha256": "1c4ea618a639817109a12a6f21d6d3fcd3039b275404b27235a9f83a22d35f2e",
      "externalId": null,
      "label": "v3audit-ejemplos factura F-1024",
      "constanciaSha256": "66d05b52d3f61e73ce60296b9ae5e490bf5d4b039a5ef92a84dc8e24e8c98957",
      "serialNumber": "SANDBOX-609299F0EAFB4A2B",
      "sealedAt": "2026-07-11T14:33:19Z",
      "policyOid": null,
      "tsaName": "AllSign Sandbox — NOM-151 Mock (no validez legal)",
      "environment": "test",
      "sandbox": true,
      "createdAt": "2026-07-11T14:33:19.564000Z"
    }
  ],
  "hasMore": true,
  "limit": 5,
  "nextCursor": "<cursor>"
}
```

Grabado en el entorno interno de AllSign con una key de sandbox · backend `24c0469` · 8 oct 2026, 06:12 (hora CDMX) · test `docs-checks-v3/tests/ejemplos/constancias.ejemplos.spec.ts`

## Verificar una constancia

POST `/constancias/verify`

Corre los **cuatro** checks criptográficos sobre una constancia y devuelve el resultado por criterio. | Check | Qué prueba | |---|---| | `integrity` | El hash sellado dentro del token es el de tu documento | | `chainOfTrust` | El certificado firmante encadena a la raíz de **Secretaría de Economía** | | `cmsSignature` | La firma CMS del token es válida (RFC 5652) | | `certValidity` | El certificado estaba vigente **al momento del sellado** | Los cuatro son necesarios y ninguno implica a otro: un imprint correcto no dice nada de quién firmó, y una firma válida de un emisor cualquiera no acredita nada. **`status` es tri-estado, no un booleano** (ETSI EN 319 102-1): - `VALID` — los cuatro checks pasaron. - `INVALID` — afirmación fuerte: el artefacto está mal (el documento no es el que se selló, o el emisor no es acreditado). - `INDETERMINATE` — **no pudimos concluir**. Token ilegible, o un check que no se pudo completar. *No* significa que la constancia sea falsa. Esa distinción importa: colapsar `INDETERMINATE` en `INVALID` te haría reportar «tu constancia es falsa» cuando el problema es de nuestro lado. > **Esto es una conveniencia, no una autoridad.** AllSign no es PSC acreditado, y preguntarle al emisor si su propio artefacto es válido no constituye prueba ante un tercero. Para eso está la verificación independiente: baja la raíz en `/v3/constancias/certchain` y verifica con `openssl` por tu cuenta. El valor de este endpoint es que valida el certificado del PSC contra la raíz correcta, que es el paso que se suele equivocar. Puedes mandar `constancia` (base64) + `hashSha256`, **o** solo `constanciaId` si la emitimos nosotros — en ese caso el hash sale de nuestro registro.

#### Parámetros

-   `AllSign-Version` enum header
    
    Fecha del contrato contra la que quieres resolver la petición. Si la omites se sirve la versión vigente; una fecha desconocida responde 400 `UNSUPPORTED_API_VERSION`.
    
    Valores: `2026-07-11`
    

#### Cuerpo de la petición

application/json

-   `hashSha256` string puede ser null
    
    de 64 a 64 caracteres
    
-   `constancia` string puede ser null
    
-   `constanciaId` string puede ser null
    

#### Devuelve

**200** Resultado de la verificación. Revisa `status` **y** `checks`; un `INDETERMINATE` con `errors` te dice qué no se pudo comprobar.

Ver los 12 atributos de la respuesta

-   `status` enum requerido
    
    Valores: `VALID` `INDETERMINATE` `INVALID`
    
-   `reason` string requerido
    
-   `hashSha256` string puede ser null
    
-   `checks` objeto puede ser null
    
    Resultado POR CRITERIO. Los cuatro checks son independientes. Se publican por separado a propósito: un `INVALID` sin desglose no le dice al cliente si el documento fue alterado (integridad) o si el emisor no está acreditado (cadena) — son problemas distintos con remedios distintos.
    
    Ver 4 atributos hijos
    
    -   `checks.integrity` boolean requerido
        
    -   `checks.chainOfTrust` boolean requerido
        
    -   `checks.cmsSignature` boolean requerido
        
    -   `checks.certValidity` boolean requerido
        
    
-   `sealedHash` string puede ser null
    
-   `sealedAt` string puede ser null
    
-   `serialNumber` string puede ser null
    
-   `policyOid` string puede ser null
    
-   `tsaName` string puede ser null
    
-   `signerSubject` string puede ser null
    
-   `signerIssuer` string puede ser null
    
-   `errors` array de string
    

Errores posibles (problem+json): [401](https://allsign.io/developers/docs/errors) [403](https://allsign.io/developers/docs/errors) [404](https://allsign.io/developers/docs/errors) [422](https://allsign.io/developers/docs/errors) [429](https://allsign.io/developers/docs/errors)

**cURL**

```
curl -X POST 'https://api.allsign.io/v3/constancias/verify' \
  -H "Authorization: Bearer $ALLSIGN_API_KEY" \
  -H "AllSign-Version: 2026-07-11" \
  -H "Content-Type: application/json" \
  -d '{
  "constanciaId": "cst_83c44d9ca7c7479cb88bd7b09c08f6ff",
  "hashSha256": "683cd72903d1381092c59cb519b999124fdd04954fcafb37cb1207f6bfba9e01"
}'
```

**Node**

```
const respuesta = await fetch('https://api.allsign.io/v3/constancias/verify', {
    method: 'POST',
    headers: {
        Authorization: `Bearer ${process.env.ALLSIGN_API_KEY}`,
        'AllSign-Version': '2026-07-11',
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({
        constanciaId: 'cst_83c44d9ca7c7479cb88bd7b09c08f6ff',
        hashSha256: '683cd72903d1381092c59cb519b999124fdd04954fcafb37cb1207f6bfba9e01',
    }),
});
console.log(respuesta.status, await respuesta.json());
```

**Python**

```
import os

import requests

respuesta = requests.post(
    "https://api.allsign.io/v3/constancias/verify",
    headers={
        "Authorization": f"Bearer {os.environ['ALLSIGN_API_KEY']}",
        "AllSign-Version": "2026-07-11",
    },
    json={
        "constanciaId": "cst_83c44d9ca7c7479cb88bd7b09c08f6ff",
        "hashSha256": "683cd72903d1381092c59cb519b999124fdd04954fcafb37cb1207f6bfba9e01",
    },
)
print(respuesta.status_code, respuesta.json())
```

**Respuesta · 200**

```
{
  "status": "INDETERMINATE",
  "reason": "Artefacto de sandbox (AllSign NOM-151 Mock): sin validez legal y no verificable por diseño. Emite con una API key de environment `live` para obtener una constancia real verificable.",
  "hashSha256": "683cd72903d1381092c59cb519b999124fdd04954fcafb37cb1207f6bfba9e01",
  "checks": {
    "integrity": false,
    "chainOfTrust": false,
    "cmsSignature": false,
    "certValidity": false
  },
  "sealedHash": null,
  "sealedAt": null,
  "serialNumber": null,
  "policyOid": null,
  "tsaName": null,
  "signerSubject": null,
  "signerIssuer": null,
  "errors": [
    "Artefacto de sandbox (AllSign NOM-151 Mock): sin validez legal y no verificable por diseño. Emite con una API key de environment `live` para obtener una constancia real verificable."
  ]
}
```

Grabado en el entorno interno de AllSign con una key de sandbox · backend `24c0469` · 8 oct 2026, 06:12 (hora CDMX) · test `docs-checks-v3/tests/ejemplos/constancias.ejemplos.spec.ts`

## Raíz de confianza para verificar offline

GET `/constancias/certchain`

Devuelve en PEM el certificado raíz de la **Autoridad Certificadora Raíz Segunda de Secretaría de Economía** — el `-CAfile` que necesitas para verificar una constancia sin depender de AllSign. ⚠️ **`openssl ts -verify` rechaza una constancia NOM-151 con la invocación normal.** No es que la constancia esté mal: el certificado firmante **no lleva el Extended Key Usage `Time Stamping`** (solo `Digital Signature, Non Repudiation`), porque una constancia de conservación no es un sello de tiempo puro. Sin el flag correcto verás `unsuitable certificate purpose` y concluirás, equivocadamente, que la constancia es inválida. El flag es **`-purpose any`**. Y como SeguriData entrega un **token CMS pelado** (no un `TimeStampResp`), hace falta además **`-token_in`**. Si tu versión de `openssl` aun así se niega, `openssl cms -verify -purpose any` comprueba firma y cadena — **pero no compara el message imprint**, así que en ese camino tienes que extraer el `TSTInfo` y comparar el hash tú mismo. > Servimos esta raíz **por conveniencia, no como autoridad**: no somos PSC acreditado. La fuente autoritativa es la Secretaría de Economía; si tu proceso requiere rigor, bájala de ahí y compara. El archivo que servimos se valida contra su fingerprint SHA-256 antes de entregarse.

#### Parámetros

-   `AllSign-Version` enum header
    
    Fecha del contrato contra la que quieres resolver la petición. Si la omites se sirve la versión vigente; una fecha desconocida responde 400 `UNSUPPORTED_API_VERSION`.
    
    Valores: `2026-07-11`
    

#### Devuelve

**200** El certificado raíz en PEM.

Errores posibles (problem+json): [401](https://allsign.io/developers/docs/errors) [403](https://allsign.io/developers/docs/errors) [422](https://allsign.io/developers/docs/errors) [429](https://allsign.io/developers/docs/errors) [503](https://allsign.io/developers/docs/errors)

**cURL**

```
curl 'https://api.allsign.io/v3/constancias/certchain' \
  -H "Authorization: Bearer $ALLSIGN_API_KEY" \
  -H "AllSign-Version: 2026-07-11"
```

**Node**

```
import { writeFileSync } from 'node:fs';

const respuesta = await fetch('https://api.allsign.io/v3/constancias/certchain', {
    headers: {
        Authorization: `Bearer ${process.env.ALLSIGN_API_KEY}`,
        'AllSign-Version': '2026-07-11',
    },
});
writeFileSync('descarga.bin', Buffer.from(await respuesta.arrayBuffer()));
```

**Python**

```
import os
from pathlib import Path

import requests

respuesta = requests.get(
    "https://api.allsign.io/v3/constancias/certchain",
    headers={
        "Authorization": f"Bearer {os.environ['ALLSIGN_API_KEY']}",
        "AllSign-Version": "2026-07-11",
    },
)
Path("descarga.bin").write_bytes(respuesta.content)
```

**Respuesta · 200**

```
<archivo application/x-pem-file>
```

Grabado en el entorno interno de AllSign con una key de sandbox · backend `24c0469` · 8 oct 2026, 06:12 (hora CDMX) · test `docs-checks-v3/tests/ejemplos/constancias.ejemplos.spec.ts`
