AlchemyCode API docs

Tu primera consulta en 5 minutos

Esta guía asume que ya recibiste una invitación. Al terminar tendrás una empresa registrada, su e.firma cargada y un job con la Constancia de Situación Fiscal en la mano.

¿Aún no tienes invitación? El registro público está cerrado durante la beta. Pide acceso a equipo@alchemycode.dev con el RFC de la empresa y el volumen estimado de consultas.
Atajo de sandbox: toda cuenta nueva incluye una llave ck_test_. Puedes recorrer esta guía completa con ella y datos simulados; consulta Sandbox antes de usar datos reales.

Antes de empezar

NecesitasPara qué
Invitación vigenteCrear la cuenta y la primera llave. Expira en 7 días por omisión.
RFC y razón socialDar de alta la empresa. El RFC debe existir en el padrón del SAT.
e.firma (.cer, .key y contraseña)Los servicios del SAT y la opinión IMSS la usan. No la compartas por correo.
Usuario y contraseña de IMSS / InfonavitSólo si vas a consultar buzón, opinión IMSS u opinión Infonavit.
La e.firma debe corresponder al RFC de la empresa. Si el certificado pertenece a otro RFC, la API rechaza la carga con FILE_INVALID.

Paso 1 · Crea tu cuenta

Abre el enlace de la invitación y define tu contraseña. La cuenta se crea con el plan Invitación · Beta: 2,000 unidades al mes, 60 peticiones por minuto y hasta 5 empresas.

Si prefieres automatizarlo, la aceptación también es un endpoint:

Shell
curl -sS -X POST "https://api.434alchemycode.com/v1/auth/invitations/accept" \
  -H "Content-Type: application/json" \
  -d '{
    "token": "inv_9c2f4b8e1a7d3f5c6b0e2a4d8f1c3b7e",
    "name": "Ana Beltrán",
    "password": "UnaClaveSegura2026!",
    "account_name": "Omnicom Servicios"
  }'

La respuesta incluye tu primera llave de prueba. Guárdala en ese momento: no se vuelve a mostrar.

JSON
{
  "object": "account",
  "account": {"id": "9b2f5c1e-7a3d-4f8b-9c21-6d4e8a0b5f17", "name": "Omnicom Servicios", "slug": "omnicom-servicios"},
  "api_key": {
    "key": "ck_test_7f3a91c2m4p8q1w7x5n3v9b6t0",
    "prefix": "ck_test_7f3a91c2",
    "environment": "test",
    "warning": "Guarda esta llave de prueba: no volverá a mostrarse."
  },
  "redirect": "/console"
}

Paso 2 · Registra la empresa

Una empresa es el RFC sobre el que se ejecutan los servicios. Cada cuenta administra las suyas y no puede ver las de otra cuenta, aunque conozca el UUID.

Shell
curl -sS -X POST "https://api.434alchemycode.com/v1/companies" \
  -H "Authorization: Bearer $ALCHEMY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "rfc": "OMX2503255F9",
    "legal_name": "OMNICONMX, S.A. de C.V.",
    "tax_regime": "601",
    "external_ref": "OMNICOM-001"
  }'

El servicio infiere person_type del RFC: 12 caracteres es persona moral, 13 es persona física. Guarda el id que devuelve: lo usarás como company_id en cada consulta.

JSON
{
  "id": "9b2f5c1e-7a3d-4f8b-9c21-6d4e8a0b5f17",
  "object": "company",
  "rfc": "OMX2503255F9",
  "legal_name": "OMNICONMX, S.A. de C.V.",
  "person_type": "moral",
  "tax_regime": "601",
  "status": "active",
  "credentials": {
    "fiel": {"configured": false, "status": null},
    "imss": {"configured": false},
    "infonavit": {"configured": false}
  }
}

Paso 3 · Carga la e.firma

Es un multipart/form-data con tres campos: cer, key y password. La API valida que el certificado abra, que la llave corresponda y que el RFC coincida.

Shell
curl -sS -X POST "https://api.434alchemycode.com/v1/companies/9b2f5c1e-7a3d-4f8b-9c21-6d4e8a0b5f17/credentials/sat" \
  -H "Authorization: Bearer $ALCHEMY_API_KEY" \
  -H "Accept: application/json" \
  -F "cer=@./omnicom.cer;type=application/x-x509-ca-cert" \
  -F "key=@./omnicom.key;type=application/octet-stream" \
  -F "password=$FIEL_PASSWORD"

Si el certificado está vencido, la carga se acepta con status: "expired" pero los servicios del SAT fallarán con FIEL_EXPIRED. Carga una e.firma vigente.

JSON
{
  "object": "sat_credential",
  "company_id": "9b2f5c1e-7a3d-4f8b-9c21-6d4e8a0b5f17",
  "status": "valid",
  "rfc": "OMX2503255F9",
  "serial": "3A7F19C2B84E",
  "valid_to": "2028-03-18T00:00:00+00:00",
  "cer_sha256": "b7c1e0a4f8d29c63507a4e1b8d3f2c6a9e0b4d7c1a8f5e2d3b6c9a0f4e7d1c28",
  "message": "e.firma validada y cifrada. Lista para consultar el SAT."
}
La contraseña de la e.firma viaja en el cuerpo y se cifra antes de guardarse; nunca se registra en logs ni se devuelve en las respuestas. Usa TLS y un formulario de tu backend, no de tu frontend.

Paso 4 · Ejecuta la primera consulta

La Constancia de Situación Fiscal es asíncrona: responde 202 Accepted con un job y el resultado se consulta después.

Shell
curl -i -sS -X POST "https://api.434alchemycode.com/v1/sat/constancias" \
  -H "Authorization: Bearer $ALCHEMY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 6f1c2c7a-3d0e-4a51-9b0e-5c2a7f9d1e44" \
  -d '{
    "company_id": "9b2f5c1e-7a3d-4f8b-9c21-6d4e8a0b5f17",
    "include_pdf": true,
    "wait": false
  }'
HTTP
HTTP/1.1 202 Accepted
X-Request-Id: req_8f2c1a4b7d9e3f60
Content-Type: application/json

{
  "object": "job",
  "id": "4d1f8c0a-6b2e-4c93-8f51-2a7d9e3b6c08",
  "service": "sat.constancia",
  "status": "queued",
  "company_id": "9b2f5c1e-7a3d-4f8b-9c21-6d4e8a0b5f17",
  "created_at": "2026-10-31T16:42:07.318920+00:00",
  "units": 0,
  "result": null,
  "files": [],
  "links": {"self": "/v1/jobs/4d1f8c0a-6b2e-4c93-8f51-2a7d9e3b6c08"}
}

Guarda el id del job. Si usaste Idempotency-Key, un reintento con el mismo cuerpo devuelve el mismo job en lugar de crear otro.

Paso 5 · Lee el resultado

Consulta el job cada 2 segundos. Cuando status sea succeeded, el resultado está en result y los archivos en files.

Shell
curl -sS "https://api.434alchemycode.com/v1/jobs/4d1f8c0a-6b2e-4c93-8f51-2a7d9e3b6c08" \
  -H "Authorization: Bearer $ALCHEMY_API_KEY"
JSON
{
  "object": "job",
  "id": "4d1f8c0a-6b2e-4c93-8f51-2a7d9e3b6c08",
  "service": "sat.constancia",
  "status": "succeeded",
  "company_id": "9b2f5c1e-7a3d-4f8b-9c21-6d4e8a0b5f17",
  "created_at": "2026-10-31T16:42:07.318920+00:00",
  "started_at": "2026-10-31T16:42:08.041228+00:00",
  "finished_at": "2026-10-31T16:44:12.882014+00:00",
  "units": 1,
  "result": {
    "rfc": "OMX2503255F9",
    "razon_social": "OMNICONMX, S.A. de C.V.",
    "tipo_persona": "moral",
    "regimen_fiscal": {
      "clave": "601",
      "descripcion": "General de Ley Personas Morales"
    },
    "fecha_inicio_operaciones": "2019-04-12",
    "estatus_padron": "Activo",
    "domicilio": {
      "calle": "Av. Insurgentes Sur",
      "numero_exterior": "1602",
      "numero_interior": "Piso 12",
      "colonia": "Crédito Constructor",
      "codigo_postal": "03940",
      "municipio": "Benito Juárez",
      "estado": "Ciudad de México",
      "pais": "México"
    },
    "obligaciones": [
      {
        "clave": "1",
        "descripcion": "Presentar declaraciones mensuales de ISR",
        "vencimiento": "2026-12-31",
        "estatus": "Vigente"
      },
      {
        "clave": "2",
        "descripcion": "Presentar declaraciones mensuales de IVA",
        "vencimiento": "2026-12-31",
        "estatus": "Vigente"
      },
      {
        "clave": "3",
        "descripcion": "Presentar declaración anual de personas morales",
        "vencimiento": "2027-03-31",
        "estatus": "Vigente"
      },
      {
        "clave": "5",
        "descripcion": "Expedir comprobantes fiscales digitales por internet",
        "vencimiento": "2026-12-31",
        "estatus": "Vigente"
      }
    ],
    "actividad_economica": {
      "clave": "541110",
      "descripcion": "Servicios de consultoría administrativa",
      "porcentaje": 100
    },
    "pdf": {
      "paginas": 3,
      "generado_en": "2026-10-31T16:44:12+00:00"
    }
  },
  "files": [
    {
      "id": "a91c4f7e2b6d48c05e3a1f9b7d2c6084",
      "name": "constancia-situacion-fiscal.pdf",
      "content_type": "application/pdf",
      "kind": "document",
      "size": 184320,
      "sha256": "b7c1e0a4f8d29c63507a4e1b8d3f2c6a9e0b4d7c1a8f5e2d3b6c9a0f4e7d1c28",
      "url": "/v1/files/a91c4f7e2b6d48c05e3a1f9b7d2c6084?p=OWIyZjVjMWUtN2EzZC00ZjhiLTljMjEtNmQ0ZThhMGI1ZjE3&exp=1793410512&sig=3f9c1d7a2b6e4c8d0f1a5b9e3c7d2f6a8b0c4e2d"
    }
  ],
  "error": null,
  "warnings": [],
  "sandbox": false,
  "links": {
    "self": "/v1/jobs/4d1f8c0a-6b2e-4c93-8f51-2a7d9e3b6c08"
  }
}

La URL del PDF es firmada y expira a los 15 minutos. Si necesitas el archivo más tarde, vuelve a consultar el job: la API regenera la URL mientras el job no expire (72 horas).

En producción no hagas polling agresivo desde el navegador. Usa un webhook job.succeeded y consulta el job una sola vez. Ver Webhooks y Trabajos.

Siguientes pasos