Skip to content

Referencia de la API Pública de Desarrollador ​

El backend de OIM proporciona una API REST versionada y limpia para compilar medidas de diseño, empaquetar archivos interactivos firmados y consultar las claves criptográficas públicas.

URL Base: https://api.oim.media


1. Autenticación y Claves API ​

EndpointClaveLímite
POST /v1/oim/packageObligatoria (401 OIM_E_AUTH_REQUIRED sin ella)30 / minuto por IP, más la cuota mensual de firmas
POST /v1/oim/compileOpcional60 / minuto por IP
POST /v1/oim/extractNo30 / minuto por IP
GET /v1/media/keysNo—

Las claves de API son exclusivas del Plan Enterprise; una clave de otro plan se rechaza con 403. Envía la clave en una cabecera:

http
X-API-Key: TU_CLAVE_DE_DESARROLLADOR

o como token bearer:

http
Authorization: Bearer TU_CLAVE_DE_DESARROLLADOR

Guarda la clave en tu servidor

La clave firma a cargo de tu cuota. No la pongas en código de navegador ni en una app que distribuyas, y no la mandes en la URL (?api_key=): las URLs quedan en registros e historiales. Llama a la API desde tu backend.

Evita peticiones que fallarán

  • No llames a /package sin clave: siempre responde 401.
  • Valida antes de firmar: los rechazos 400 y 403 llegan antes de consumir cuota, pero cuentan para el límite por minuto.
  • Ante 429, espera los segundos de Retry-After antes de reintentar; reintentar en bucle alarga el bloqueo.
  • Para reintentar una firma tras un corte de red, usa Idempotency-Key (ver abajo): no se cobra dos veces.

Límites de uso: RateLimit-* y Retry-After ​

Los endpoints con límite responden con RateLimit-Limit (peticiones permitidas en la ventana), RateLimit-Remaining (las que quedan en esta ventana) y RateLimit-Reset (segundos hasta que la ventana se reinicia). Pasado el límite la respuesta es 429 con Retry-After: los segundos que hay que esperar antes de reintentar.

Seguir una petición: X-Request-ID ​

Cada respuesta lleva una cabecera X-Request-ID. Si algo falla, inclúyela al reportar el problema: identifica tu petición en nuestros registros. También puedes enviar tu propio X-Request-ID (de 8 a 128 caracteres entre A-Z, a-z, 0-9, ., _ o -) y la respuesta lo devuelve igual; cualquier otro valor se sustituye por uno nuevo.

Cabeceras de seguridad ​

Cada respuesta incluye cabeceras de seguridad defensivas:

  • Cross-Origin-Resource-Policy: cross-origin
  • Strict-Transport-Security: max-age=63072000; includeSubDomains
  • X-Content-Type-Options: nosniff
  • X-Frame-Options: DENY
  • Referrer-Policy: no-referrer

Límites de carga en peticiones ​

  • Los endpoints JSON que no son de subida aceptan cargas de hasta 5 MB. La codificación fragmentada (Transfer-Encoding: chunked) no está admitida en endpoints sin subida y se rechaza con 400 Bad Request.
  • Los endpoints de subida y compilación aceptan archivos de hasta 50 MB (MAX_UPLOAD_SIZE). Las imágenes base están limitadas a 8192 px por lado y 16 MP (16.777.216 píxeles).

2. Compilar Medidas: POST /v1/oim/compile ​

Convierte coordenadas crudas en píxeles de pantalla a porcentajes relativos adaptativos y unidades cqw.

  • Endpoint: POST /v1/oim/compile
  • Límite de Peticiones: 60 peticiones / minuto
  • Cuerpo de Petición (application/json):
json
{
  "canvas_width": 1080,
  "canvas_height": 1080,
  "slots_raw": [
    {
      "id": "hero_text",
      "type": "text",
      "x_px": 108,
      "y_px": 216,
      "width_px": 864,
      "height_px": 120,
      "content": {
        "en": "Empower your media",
        "es": "Potencia tus medios"
      }
    }
  ]
}
  • Respuesta (200 OK): Retorna el objeto OimMetadata con coordenadas normalizadas.

3. Empaquetar y Firmar Medio: POST /v1/oim/package ​

Combina una imagen PNG horneada limpia (Capa −1) con los metadatos compilados, firma el payload con ECDSA P-256 y genera el binario .oim.png final.

  • Endpoint: POST /v1/oim/package
  • Autenticación: clave de API obligatoria
  • Límite de Peticiones: 30 peticiones / minuto, más la cuota mensual de firmas
  • Formato de Petición: multipart/form-data
  • Parámetros:
    • file: Archivo binario de imagen PNG horneada (Capa −1). Hasta 50 MB, como máximo 8192 px por lado y como máximo 16.777.216 píxeles (16 MP). Superar los límites de imagen devuelve 400 Bad Request.
    • metadata: Cadena JSON serializada conforme a OimMetadataSchema.
bash
curl -X POST https://api.oim.media/v1/oim/package \
  -H "X-API-Key: $OIM_API_KEY" \
  -F "[email protected]" \
  -F "[email protected]" \
  --output resultado.oim.png
  • Respuesta (200 OK): Flujo binario image/png con el chunk OIM_Data incrustado y firmado.

  • Rechazos por la cuenta (403, también en /v1/oim/compile): no se firma nada ni se consume cuota.

    codeSignificado
    OIM_E_POLICIES_PENDINGLa cuenta tiene Términos o Política de Privacidad nuevos ya en vigor y sin aceptar. Se aceptan en https://oim.media/#/politicas y se reintenta.

Reintentar sin pagar dos veces: Idempotency-Key ​

Cada firma consume una unidad de la cuota mensual. Si la conexión se corta después de que el servidor firmara, un reintento se cobraría otra vez. Para evitarlo, envía una cabecera Idempotency-Key con un valor que generes una vez por petición, por ejemplo un UUID, y envía el mismo valor al reintentar esa petición.

  • Durante 24 horas, un reintento con la misma clave y el mismo contenido se vuelve a firmar sin consumir cuota.
  • La misma clave con otro contenido se rechaza con 422. Usa una clave nueva para cada archivo nuevo.
  • Una clave mal formada, fuera de 16–128 caracteres de A-Z a-z 0-9 _ -, se rechaza con 400.
  • La cabecera es opcional: sin ella, cada petición se cobra como siempre.
bash
curl -X POST https://api.oim.media/v1/oim/package \
  -H "X-API-Key: $OIM_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -F "[email protected]" \
  -F "[email protected]" \
  --output resultado.oim.png

Una imagen base más ligera: base_optimization ​

El servidor siempre guarda la imagen base sin un canal de transparencia que no se usa: una base RGBA opaca pasa a RGB, con los mismos píxeles. Un campo opcional del formulario pide más:

ValorQué hace
lossless (por defecto)Píxeles idénticos. Solo se quita la transparencia que no se usa.
paletteReduce una base opaca a 256 colores. Mucho más pequeña (alrededor de un 60 % en ilustraciones grandes), pero los píxeles cambian: los degradados pueden mostrar bandas leves.
  • Una base con transparencia real nunca se reduce a paleta: se guarda sin pérdida.
  • La cabecera de respuesta X-OIM-Base-Optimization dice cuál se aplicó.
  • Cualquier otro valor se rechaza con 400 y el código OIM_E_BASE_OPTIMIZATION_INVALID, antes de consumir cuota.

Marcas de texto ​

Un texto con etiquetas de marca mal formadas (una marca desconocida, una etiqueta sin cerrar o anidada, una llave sola que no es etiqueta; ver Marcas de texto en la especificación del formato) se rechaza con 400 y el código OIM_E_TEXT_MARKS_INVALID, indicando la capa y el idioma, antes de consumir cuota. Así, un .oim firmado solo lleva textos bien formados.

  • Con Idempotency-Key, la opción forma parte del contenido: la misma clave con otra opción se rechaza con 422.
bash
curl -X POST https://api.oim.media/v1/oim/package \
  -H "X-API-Key: $OIM_API_KEY" \
  -F "[email protected]" \
  -F "[email protected]" \
  -F "base_optimization=palette" \
  --output resultado.oim.png

4. Extraer Metadatos: POST /v1/oim/extract ​

Lee e inspecciona un archivo .oim.png existente, extrayendo tanto el JSON de metadatos descomprimido como la imagen horneada de Capa −1.

  • Endpoint: POST /v1/oim/extract

  • Formato de Petición: multipart/form-data

  • Parámetros:

    • file: Binario .oim.png subido (solo PNG, hasta 50 MB).
  • Límite de Peticiones: 30 peticiones / minuto

  • Respuesta (200 OK):

json
{
  "image_base64": "iVBORw0KGgo...",
  "metadata": { "version": "1.27.2", "signature": "MEQCIF+...", "slots": [] },
  "revoked": false
}

metadata lleva el JSON del archivo tal cual, o { "error": ..., "slots": [] } si el PNG no contiene datos OIM. revoked es true si el archivo fue revocado.


5. Claves Criptográficas Públicas: GET /v1/media/keys ​

Expone las claves públicas activas e históricas de verificación en formato estándar JSON Web Key (JWK).

  • Endpoint: GET /v1/media/keys
  • Autenticación: Pública (no requiere clave)
  • Respuesta (200 OK):
json
{
  "keys": [
    {
      "kty": "EC",
      "crv": "P-256",
      "x": "f83OJ3D2xFmT4v7Z2V4s8uY9xQ7...",
      "y": "x_da7W8mP2zQ9v4L1m3s8uY9xQ7...",
      "kid": "v1",
      "use": "sig"
    }
  ]
}

Los reproductores en cliente y auditores independientes utilizan estas claves JWK para verificar matemáticamente la validez de la firma sin necesidad de conectar con servidores privados.