Seal on Chain API

API REST para registro de copyright con validez legal en blockchain NEAR. Genera evidencia inmutable, certificados PDF y archivos CWR para PROs.

Base URL: https://api.sealonchain.com

🔐 Autenticación

La API utiliza API Keys para autenticar requests de terceros (PROs como SGAE, ASCAP, Unison, etc.).

💡 Endpoints públicos

Los siguientes endpoints NO requieren autenticación: /health, /docs, /api/cwr/supported-pros

Obtener una API Key

Para obtener una API Key, contacta con Spleet proporcionando:

  • Nombre de tu organización
  • Email de contacto técnico
  • Casos de uso previstos

Usar la API Key

Incluye tu API Key en el header X-API-Key de cada request:

cURLcurl -H "X-API-Key: sk_live_tu_api_key_aqui" \
     https://api.spleet.ai/api/cwr/{masterHash}
JavaScriptfetch('https://api.spleet.ai/api/cwr/{masterHash}', {
  headers: {
    'X-API-Key': 'sk_live_tu_api_key_aqui'
  }
})

Formato de API Key

PrefijoEntornoEjemplo
sk_live_Producciónsk_live_Abc123xyz...
sk_test_Desarrollosk_test_Abc123xyz...

Scopes (Permisos)

Cada API Key tiene permisos específicos:

ScopeDescripciónEndpoints
cwr:readGenerar y validar CWR/api/cwr/*
verify:readVerificar hashes/api/verify/*
register:writeRegistrar copyrights/api/register

Rate Limits

Los límites por defecto son:

LímiteValor
Por minuto60 requests
Por día10,000 requests
⚠️ Headers de Rate Limit

Las respuestas incluyen headers X-RateLimit-Limit-Minute y X-RateLimit-Limit-Day con tus límites.

Errores de Autenticación

CódigoErrorDescripción
401API key requeridaNo se incluyó el header X-API-Key
401API key inválidaLa key no existe o está desactivada
403Permisos insuficientesLa key no tiene el scope necesario
429Rate limit excedidoDemasiadas requests, espera antes de reintentar

Ejemplo de error 401:

JSON{
  "success": false,
  "error": "API key requerida",
  "hint": "Incluye el header X-API-Key con tu API key",
  "docs": "/docs#authentication"
}

Health Check

GET /health

Verifica el estado del servicio, configuración de NEAR y conexión a base de datos.

Response 200

JSON{
  "status": "ok",
  "service": "seal-on-chain",
  "version": "1.1.0",
  "near": {
    "networkId": "testnet",
    "contractName": "seal-on-chain.testnet"
  },
  "database": {
    "configured": true,
    "connected": true
  }
}

Register Copyright

POST /api/register

Registra un copyright en blockchain NEAR. Genera evidencia JSON, calcula hash maestro, ancla en blockchain y genera certificado PDF.

Request Body

JSON{
  "audioHash": "a1b2c3d4...64chars",
  "signedPdfHash": "b2c3d4e5...64chars",
  "authors": [
    {
      "party_id": "uuid",
      "name": "Juan Pérez",
      "roles": ["COMPOSER", "PRODUCER"],
      "split_percentage": 50,
      "ipi_number": "1234567890",
      "pro_name": "SGAE"
    }
  ],
  "metadata": {
    "external_work_id": "work_001",
    "work_title": "Mi Canción",
    "isrc": "ESXXX2400001"
  }
}

Response 201

JSON{
  "success": true,
  "data": {
    "evidence_id": "evid_1705312200000_550e8400",
    "master_hash": "c3d4e5f6...64chars",
    "near_transaction_hash": "ABC123...",
    "certificate_url": "https://...",
    "arweave_uri": "arweave://bafyexample"
  }
}

Status Codes

201Registro creado exitosamente
400Datos de entrada inválidos
409Hash ya registrado
500Error interno

Verify Hash

GET /api/verify/:hash

Verifica si un hash está registrado en blockchain NEAR y retorna información del registro.

Path Parameters

ParámetroTipoDescripción
hashstringHash SHA-256 (64 caracteres hexadecimales)

Response 200

JSON{
  "success": true,
  "data": {
    "master_hash": "c3d4e5f6...",
    "exists": true,
    "registered_at": "2024-01-15T10:30:00Z",
    "near_transaction_hash": "ABC123...",
    "authors": [...],
    "certificate_url": "https://..."
  }
}

🎵 Generate CWR

💡 ¿Qué es CWR?

CWR (Common Works Registration) es el estándar de la industria musical para comunicar obras entre editores y PROs como SGAE, ASCAP, BMI, etc.

GET /api/cwr/:masterHash

Genera un archivo CWR 2.1 a partir del master hash de un registro. Compatible con SGAE, ASCAP, BMI y otras PROs.

Path Parameters

ParámetroTipoDescripción
masterHashstringHash SHA-256 del registro

Query Parameters

ParámetroTipoDefaultDescripción
receiverIdstring-Código PRO: SGAE, ASCAP, BMI...
formatstringfilefile (descarga) o json
validatestringtrueIncluir warnings de validación

Ejemplo

cURLcurl -O "https://api.sealonchain.com/api/cwr/32a981bee1d6b...?receiverId=SGAE"

Response (format=json)

JSON{
  "success": true,
  "data": {
    "filename": "CW20241115_MI_CANCION_550E84.V21",
    "stats": {
      "totalRecords": 14,
      "totalWriters": 2
    },
    "cwr_content": "HDRSPLEET...",
    "receiver": {
      "id": "SGAE",
      "name": "Sociedad General de Autores y Editores"
    }
  }
}

Tipos de Registro CWR

HDR
File Header
GRH
Group Header
NWR
New Work
SPU
Publisher
SWR
Writer
SWT
Writer Territory
PWR
Publisher for Writer
PER
Performing Artist
REC
Recording Detail
TRL
File Trailer

Validate for CWR

GET /api/cwr/validate/:masterHash

Valida si un registro tiene los datos necesarios para generar un CWR, sin generarlo.

Response 200

JSON{
  "success": true,
  "data": {
    "can_generate_cwr": true,
    "validation": {
      "errors": [],
      "warnings": [
        "Autor \"Juan Pérez\" no tiene IPI Number - requerido para registro en PROs",
        "Autor \"Juan Pérez\" no tiene PRO asignada (SGAE, ASCAP, etc.)"
      ]
    },
    "work_info": {
      "title": "Mi Canción",
      "authors_count": 2,
      "has_isrc": true
    }
  }
}
💡 Nota sobre ISWC: El código ISWC (International Standard Musical Work Code) NO se valida porque es asignado por las PROs (SGAE, ASCAP, etc.) después de registrar la obra en su sistema.

Supported PROs

GET /api/cwr/supported-pros

Lista todas las PROs (Performing Rights Organizations) soportadas.

PROs Disponibles

SGAESociedad General de Autores🇪🇸
ASCAPAmerican Society🇺🇸
BMIBroadcast Music🇺🇸
PRSPerforming Right Society🇬🇧
GEMAGesellschaft für musik.🇩🇪
SACEMSociété des Auteurs🇫🇷
SIAESocietà Italiana🇮🇹
JASRACJapanese Society🇯🇵
SOCANCanadian Society🇨🇦
SADAICSociedad Argentina🇦🇷
SACMSociedad de México🇲🇽

📤 CWR Batch / SFTP

💡 Registro Automático de Obras en PROs

¿Cansado de registrar obras una a una en SGAE, Unison o tu PRO?

Con Spleet, cada vez que se firma un contrato, la obra se puede registrar automáticamente en tu PRO mediante archivos CWR. Solo configura tu servidor SFTP una vez y Spleet enviará los registros semanalmente o bajo demanda.

Cada editorial configura su propio destino (SGAE, ASCAP, BMI, etc.) de forma independiente.

POST /api/cwr/batch/send

Genera archivos CWR 2.1 para las obras pendientes de un team y los envía automáticamente al servidor SFTP de su PRO (SGAE, ASCAP, BMI, etc.). Procesa todos los registros que aún no han sido enviados.

Headers

HeaderValorDescripción
Content-Typeapplication/jsonTipo de contenido
X-API-KeystringAPI Key de autenticación

Request Body

JSON{
  "teamId": "uuid-del-team",
  "receiverId": "SGAE",
  "sftpConfig": {
    "host": "sftp.empresa.com",
    "port": 22,
    "username": "spleet_cwr",
    "password": "secreto",
    "remotePath": "/incoming/cwr"
  },
  "batchSize": 100,
  "fromDate": "2025-01-01T00:00:00Z"
}

Response 200

JSON{
  "success": true,
  "data": {
    "batchId": "batch_uuid",
    "status": "success",
    "totalProcessed": 15,
    "successfulUploads": 14,
    "failedUploads": 0,
    "skippedRecords": 1,
    "details": [
      {
        "masterHash": "abc123...",
        "filename": "CW20251127_CANCION_550E84.V21",
        "status": "success"
      }
    ],
    "startedAt": "2025-11-27T03:00:00Z",
    "completedAt": "2025-11-27T03:05:00Z"
  }
}

Test SFTP Connection

POST /api/cwr/batch/test-sftp

Prueba la conexión SFTP con las credenciales proporcionadas. Útil para validar la configuración antes de guardarla.

Request Body

JSON{
  "host": "sftp.empresa.com",
  "port": 22,
  "username": "spleet_cwr",
  "password": "secreto",
  "remotePath": "/incoming/cwr"
}

Response 200 (Éxito)

JSON{
  "success": true,
  "message": "Conexión SFTP exitosa",
  "details": {
    "connected": true,
    "canWrite": true,
    "remotePath": "/incoming/cwr"
  }
}

Response 500 (Error)

JSON{
  "success": false,
  "error": "ECONNREFUSED: Connection refused"
}

Batch Status

GET /api/cwr/batch/status/:batchId

Obtiene el estado de un batch de CWR específico, incluyendo detalles de cada archivo procesado.

Path Parameters

ParámetroTipoDescripción
batchIdstringUUID del batch

Response 200

JSON{
  "success": true,
  "data": {
    "id": "batch_uuid",
    "teamId": "team_uuid",
    "status": "success",
    "totalRecords": 15,
    "successfulUploads": 14,
    "failedUploads": 0,
    "skippedRecords": 1,
    "receiverId": "SGAE",
    "startedAt": "2025-11-27T03:00:00Z",
    "completedAt": "2025-11-27T03:05:00Z",
    "triggeredBy": "cron",
    "details": [
      {
        "masterHash": "abc123...",
        "filename": "CW20251127_CANCION_550E84.V21",
        "status": "success"
      },
      {
        "masterHash": "def456...",
        "status": "skipped",
        "error": "No tiene autores válidos"
      }
    ]
  }
}

Batch History

GET /api/cwr/batch/history/:teamId

Obtiene el historial de batches de CWR enviados por un team, ordenados por fecha descendente.

Path Parameters

ParámetroTipoDescripción
teamIdstringUUID del team

Query Parameters

ParámetroTipoDefaultDescripción
limitnumber10Número máximo de batches
offsetnumber0Offset para paginación

Response 200

JSON{
  "success": true,
  "data": {
    "batches": [
      {
        "id": "batch_uuid_1",
        "status": "success",
        "totalRecords": 15,
        "successfulUploads": 15,
        "failedUploads": 0,
        "receiverId": "SGAE",
        "startedAt": "2025-11-27T03:00:00Z",
        "triggeredBy": "cron"
      },
      {
        "id": "batch_uuid_2",
        "status": "partial",
        "totalRecords": 10,
        "successfulUploads": 8,
        "failedUploads": 2,
        "receiverId": "SGAE",
        "startedAt": "2025-11-20T03:00:00Z",
        "triggeredBy": "manual"
      }
    ],
    "total": 25,
    "limit": 10,
    "offset": 0
  }
}
📚 Documentación Adicional

Para más información sobre la configuración multi-tenant de CWR/SFTP, consulta:

Códigos de Error

Códigos HTTP

CódigoDescripción
200Solicitud exitosa
201Recurso creado
400Datos de entrada inválidos
404Recurso no encontrado
409Conflicto (hash ya registrado)
422Datos insuficientes
500Error interno del servidor

Tipos de Error

TipoDescripción
validation_errorDatos de entrada inválidos
blockchain_errorError con NEAR blockchain
database_errorError de base de datos
cwr_errorError generando CWR

Validaciones

Hash SHA-256

  • Exactamente 64 caracteres
  • Solo caracteres hexadecimales (0-9, a-f)

Autores

CampoRequeridoDescripción
party_idUUID del autor
nameNombre completo
rolesArray de roles
split_percentage0-100 (suma = 100%)
ipi_number⚠️Recomendado para CWR
pro_name⚠️Código PRO
⚠️ Importante para CWR

Para que el CWR sea aceptado por SGAE/ASCAP, cada autor debe tener IPI Number válido (9-11 dígitos).

Roles Válidos

Códigos CWR según CISAC CWR 2.1:

Rol SpleetCódigo CWRDescripción
COMPOSERCCompositor
LYRICISTALetrista
ARRANGERARArreglista
ADAPTERADAdaptador
TRANSLATORTRTraductor
SUB_ARRANGERSRSub-Arreglista
SUB_AUTHORSASub-Autor
PRODUCERCProductor
MIXING_ENGINEERCIngeniero de Mezcla
MASTERING_ENGINEERCIngeniero de Masterización
PERFORMER-Intérprete