Credenciales y firma

Cómo obtener tus credenciales y cómo se arma el encabezado de autenticación de cada petición.

Credenciales

Tu cuenta tiene un par de credenciales de desarrollador. Si todavía no las tienes a la mano, debes poder generarlas dando click en tu usuario en el portal de Administración de usuarios de la cuenta. Si no tienes acceso a este portal, solicita las credenciales a tu administrador de cuetna

Si no tienes cuenta, puedes obtener credenciales de prueba gratuitas. Sólo envía un correo a [email protected].

Qué esCómo tratarla
Web IDTu identificador públicoPuede ir en configuración, en el repositorio, donde sea
API keyEl secreto con el que se firma cada peticiónTrátala como una contraseña: autoriza a solicitar firmas a nombre de tu cuenta

Carga las dos desde variables de ambiente o desde tu gestor de secretos, nunca escritas en el código:

const services = FirmamexServices(
  process.env.FIRMAME_WEB_ID,
  process.env.FIRMAME_API_KEY,
);

Con un SDK

Es el camino corto: le pasas las credenciales al SDK y él arma la firma de cada petición.

Hay SDK para Node, TypeScript, PHP, Python, .NET y Java. Si tu lenguaje no está en la lista puedes llamar a la API directamente:

Directo contra la API

Cada petición lleva un encabezado Authorization con esta forma:

Authorization: signmage TU_WEB_ID:PWJhc2U2NCBkZWwgSE1BQz4=
Content-Type: application/json

La firma es base64(HMAC-SHA256(TU_API_KEY, cadenaFirmada)). Lo único que cambia entre peticiones es qué va dentro de cadenaFirmada:

PeticióncadenaFirmada
GETLa URI completa incluyendo el query string, exactamente como se envía
POST con JSONEl cuerpo JSON, re-serializado compacto (sin espacios ni salto de línea final)
POST multipartEl SHA-256 en Base64 del archivo, que además se manda en el header Content-SHA256

Dos temas importantes:

  1. En GET, la URI se firma tal como se envía, así que el orden y el encoding de los parámetros importan. Construye la URL una sola vez y firma esa misma cadena.
  2. En POST, la comparación se hace contra tu JSON re-serializado en forma compacta. Serializa una vez, firma esa cadena, y manda exactamente esos bytes.

Ejemplo completo

import { createHmac } from 'node:crypto';

const WEB_ID = process.env.FIRMAME_WEB_ID;
const API_KEY = process.env.FIRMAME_API_KEY;

function authorization(signedString) {
  const hmac = createHmac('sha256', API_KEY).update(signedString, 'utf8').digest('base64');
  return `signmage ${WEB_ID}:${hmac}`;
}

// POST: se firma el cuerpo compacto, y se manda ese mismo cuerpo.
const body = JSON.stringify({
  url_doc: { url: 'https://ejemplo.com/contrato.pdf', name: 'contrato.pdf' },
  stickers: [
    {
      authority: 'EMAIL_LINK',
      data: '[email protected]',
      page: 0,
      rect: { lx: 330, ly: 300, tx: 530, ty: 400 },
    },
  ],
});

await fetch('https://app.firmame.com/developers/json', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json', Authorization: authorization(body) },
  body,
});

// GET: se firma la ruta con su query string, tal cual.
const path = '/api/document?from=1640995200000&to=1641945600000';

await fetch(`https://app.firmame.com${path}`, {
  headers: { Authorization: authorization(path) },
});

Si recibes un 401, la guía de errores 401 recorre las causas posibles en orden.

En esta página