# Entregas DDEX > Entregue lotes DDEX ERN (4.3 recomendado) em produção, teste-os antes (nada é criado), use uploads diretos para os grandes e acompanhe o status. Entregue lotes DDEX ERN (4.3 recomendado) em produção, teste-os antes (nada é criado), use uploads diretos para os grandes e acompanhe o status. URL base `https://api.hillsmusic.com/v1`. Toda requisição envia uma chave de API: `Authorization: Bearer hm_live_…`. - Testar uma mensagem ou um lote DDEX - Entregar um lote DDEX (ERN 4.3 recomendado) - Listar entregas - Iniciar um upload direto (lotes grandes) - Situação de um upload direto - Descartar um upload direto - Confirmar um upload direto - Status da entrega ## Testar uma mensagem ou um lote DDEX `POST /v1/ddex/validate` · Escopo: `ddex:validate` ou `ddex:write` O caminho de teste: um .xml (Content-Type: application/xml) ou um .zip, verificado como uma entrega (o XML, as regras da HILLS, os arquivos de áudio, capa e vídeo, os UPCs e ISRCs em relação ao catálogo). Nada é criado: nenhum lançamento, gravação, artista, código ou entrega. O teste aparece na página DDEX do painel (Test reports). Cada verificação por etapa (pass / warning / error / skipped), o que a HILLS criaria e o veredito: would_import, would_import_with_warnings, would_be_flagged ou would_be_rejected. ddex:write também funciona. ### Parâmetros | Parâmetro | Em | Tipo | Obrigatório | Descrição | | --- | --- | --- | --- | --- | | `member_id` | query | integer | Não | O artista ou gravadora a que se destina (você mesmo, se omitido). | | `name` | query | string | Não | Nome do arquivo para um corpo bruto (padrão batch.zip, ou message.xml para XML). | ### Corpo da requisição O lote: o zip que você entrega às plataformas (XML ERN + os recursos a que ele se refere) como corpo bruto, um .xml avulso, ou o campo multipart file (com member_id como campo). Content types: `application/zip`, `application/xml`, `multipart/form-data`. ### Exemplo de requisição ```bash curl -X POST "https://api.hillsmusic.com/v1/ddex/validate?member_id=41" \ -H "Authorization: Bearer $HILLS_API_KEY" \ -H "Content-Type: application/zip" \ --data-binary @batch.zip ``` ### Resposta `200` ```json { "data": { "ern_version": "4.3", "verdict": "would_be_rejected", "summary": { "messages": 1, "releases": 1, "pass": 41, "warnings": 1, "errors": 2, "skipped": 1 }, "checks": [ { "stage": "release", "label": "Label", "status": "error", "message": "ReleaseLabelReference is required…", "field": "Release/ReleaseLabelReference" } ] } } ``` ### Erros | Status | Quando | | --- | --- | | 400 | invalid: um parâmetro está errado; field indica qual. | | 401 | unauthenticated, invalid_key, key_revoked, key_expired ou test_keys_retired. | | 403 | insufficient_scope: falta à chave o escopo; scope indica qual. account_inactive ou api_not_in_plan. | | 413 | too_large: maior do que um teste aceita; entregue-o com POST /ddex. | | 429 | busy: testes demais ao mesmo tempo; tente de novo em instantes. rate_limited: aguarde Retry-After segundos. | ## Entregar um lote DDEX (ERN 4.3 recomendado) `POST /v1/ddex` · Escopo: `ddex:write` Envie o zip que você entrega às plataformas: XML(s) ERN NewReleaseMessage com o áudio, a capa e os vídeos a que se referem. Como corpo bruto (Content-Type: application/zip, até 20 GB) ou no campo multipart file (até 512 MB). Cada lançamento vira um rascunho em member_id (o seu próprio catálogo, se omitido); um UPC que já existe atualiza o rascunho dele; remoções e atualizações de lançamentos no ar aguardam a equipe. ERN 4.3 (namespace http://ddex.net/xml/ern/43) é o recomendado; 4.2, 4.1, 3.8.x (3.8.2, 3.8.1, 3.8) e 3.7 são aceitos e lidos da mesma forma (o relatório avisa que a versão é legada); outras versões são rejeitadas. 202 com o id da entrega — consulte GET /ddex/{id}. ### Parâmetros | Parâmetro | Em | Tipo | Obrigatório | Descrição | | --- | --- | --- | --- | --- | | `member_id` | query | integer | Não | O artista ou gravadora a que se destina (você mesmo, se omitido). | | `name` | query | string | Não | Nome do arquivo para um corpo bruto (padrão batch.zip). | ### Corpo da requisição O lote: o zip que você entrega às plataformas (XML ERN + os recursos a que ele se refere) como corpo bruto, um .xml avulso, ou o campo multipart file (com member_id como campo). Content types: `application/zip`, `application/xml`, `multipart/form-data`. ### Exemplo de requisição ```bash curl -X POST "https://api.hillsmusic.com/v1/ddex?member_id=41" \ -H "Authorization: Bearer $HILLS_API_KEY" \ -H "Content-Type: application/zip" \ --data-binary @batch.zip ``` ### Resposta `202` ```json { "data": { "id": 311, "status": "queued", "environment": "production", "status_url": "/v1/ddex/311" } } ``` ### Erros | Status | Quando | | --- | --- | | 400 | invalid: um parâmetro está errado; field indica qual. | | 401 | unauthenticated, invalid_key, key_revoked, key_expired ou test_keys_retired. | | 403 | insufficient_scope: falta à chave o escopo; scope indica qual. account_inactive ou api_not_in_plan. | | 413 | too_large: acima de 20 GB (corpo bruto) ou 512 MB (multipart). | | 429 | rate_limited: aguarde Retry-After segundos. | ## Listar entregas `GET /v1/ddex` · Escopo: `ddex:write` ou `ddex:validate` Suas últimas 100 entregas DDEX, das mais recentes para as mais antigas (uploads ainda não confirmados ficam de fora). ### Exemplo de requisição ```bash curl "https://api.hillsmusic.com/v1/ddex" \ -H "Authorization: Bearer $HILLS_API_KEY" ``` ### Resposta `200` ```json { "data": [ { "id": 311, "member_id": 41, "environment": "production", "batch_name": "batch-0001.zip", "status": "done", "error": null, "message_id": "MSG-2026-0001", "ern_version": "4.3", "message_count": 1, "release_count": 1, "track_count": 12, "created_count": 1, "updated_count": 0, "flagged_count": 0, "left_out_count": 0, "release_ids": [ 912 ], "created_at": "2026-10-07T09:00:00Z", "started_at": "2026-10-07T09:00:02Z", "finished_at": "2026-10-07T09:01:10Z" } ] } ``` ### Erros | Status | Quando | | --- | --- | | 401 | unauthenticated, invalid_key, key_revoked, key_expired ou test_keys_retired. | | 403 | insufficient_scope: falta à chave o escopo; scope indica qual. account_inactive ou api_not_in_plan. | | 429 | rate_limited: aguarde Retry-After segundos. | ## Iniciar um upload direto (lotes grandes) `POST /v1/ddex/uploads` · Escopo: `ddex:write` Recomendado para zips grandes: o arquivo vai direto para o armazenamento, sem passar pela API. Envie o nome do arquivo e o tamanho em bytes (até 20 GB). Até 64 MB você recebe uma URL para fazer PUT do arquivo inteiro; acima disso, um tamanho de parte e uma URL por parte: faça PUT de cada fatia de part_size bytes (a última é menor) na URL correspondente, em qualquer ordem e em paralelo. As URLs valem por 6 horas; GET /ddex/uploads/{id} gera URLs novas para as partes que ainda faltam. Depois, POST /ddex/uploads/{id}/commit. DELETE /ddex/uploads/{id} descarta um upload que você não vai concluir; uploads não confirmados são removidos após 7 dias. ### Corpo da requisição JSON. | Campo | Tipo | Obrigatório | Descrição | | --- | --- | --- | --- | | `name` | string | Sim | O nome do arquivo (.zip ou .xml). | | `size` | integer | Sim | O tamanho do arquivo em bytes. | | `member_id` | integer | Não | O artista ou gravadora a que se destina (você mesmo, se omitido). | ### Exemplo de requisição ```bash curl -X POST "https://api.hillsmusic.com/v1/ddex/uploads" \ -H "Authorization: Bearer $HILLS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"name":"batch-0001.zip","size":1073741824,"member_id":41}' ``` ### Resposta `201` ```json { "data": { "id": 312, "status": "uploading", "environment": "production", "name": "batch-0001.zip", "size": 1073741824, "expires_in": 21600, "upload": { "method": "multipart", "url": null, "part_size": 16777216, "parts": [ { "part_number": 1, "url": "https://…" } ] }, "commit_url": "/v1/ddex/uploads/312/commit" } } ``` ### Erros | Status | Quando | | --- | --- | | 400 | invalid: um parâmetro está errado; field indica qual. | | 401 | unauthenticated, invalid_key, key_revoked, key_expired ou test_keys_retired. | | 403 | insufficient_scope: falta à chave o escopo; scope indica qual. account_inactive ou api_not_in_plan. | | 429 | rate_limited: aguarde Retry-After segundos. | ## Situação de um upload direto `GET /v1/ddex/uploads/{id}` · Escopo: `ddex:write` Um upload ainda não confirmado: URLs novas para as partes que faltam (as primeiras expiram após 6 horas), received_parts e parts_total. Depois de confirmado: o id da entrega e status_url. ### Parâmetros | Parâmetro | Em | Tipo | Obrigatório | Descrição | | --- | --- | --- | --- | --- | | `id` | path | integer | Sim | O id do upload. | ### Exemplo de requisição ```bash curl "https://api.hillsmusic.com/v1/ddex/uploads/312" \ -H "Authorization: Bearer $HILLS_API_KEY" ``` ### Resposta `200` ```json { "data": { "id": 312, "status": "uploading", "environment": "production", "name": "batch-0001.zip", "size": 1073741824, "expires_in": 21600, "upload": { "method": "multipart", "url": null, "part_size": 16777216, "parts": [ { "part_number": 7, "url": "https://…" } ] }, "commit_url": "/v1/ddex/uploads/312/commit", "received_parts": 63, "parts_total": 64 } } ``` ### Erros | Status | Quando | | --- | --- | | 401 | unauthenticated, invalid_key, key_revoked, key_expired ou test_keys_retired. | | 403 | insufficient_scope: falta à chave o escopo; scope indica qual. account_inactive ou api_not_in_plan. | | 404 | not_found: não existe, ou não é seu. | | 429 | rate_limited: aguarde Retry-After segundos. | ## Descartar um upload direto `DELETE /v1/ddex/uploads/{id}` · Escopo: `ddex:write` Descarta um upload que você não vai concluir, junto com as partes já enviadas. 409 depois de confirmado. ### Parâmetros | Parâmetro | Em | Tipo | Obrigatório | Descrição | | --- | --- | --- | --- | --- | | `id` | path | integer | Sim | O id do upload. | ### Exemplo de requisição ```bash curl -X DELETE "https://api.hillsmusic.com/v1/ddex/uploads/312" \ -H "Authorization: Bearer $HILLS_API_KEY" ``` ### Resposta `200` ```json { "data": { "id": 312, "deleted": true } } ``` ### Erros | Status | Quando | | --- | --- | | 401 | unauthenticated, invalid_key, key_revoked, key_expired ou test_keys_retired. | | 403 | insufficient_scope: falta à chave o escopo; scope indica qual. account_inactive ou api_not_in_plan. | | 404 | not_found: não existe, ou não é seu. | | 409 | already_committed: já confirmado; não pode ser descartado. | | 429 | rate_limited: aguarde Retry-After segundos. | ## Confirmar um upload direto `POST /v1/ddex/uploads/{id}/commit` · Escopo: `ddex:write` Verifica se todas as partes chegaram com o tamanho certo e coloca o lote na fila exatamente como POST /ddex. 409 upload_incomplete lista as partes ausentes e as de tamanho errado (envie-as e confirme de novo). 202 com o id da entrega; consulte GET /ddex/{id}. ### Parâmetros | Parâmetro | Em | Tipo | Obrigatório | Descrição | | --- | --- | --- | --- | --- | | `id` | path | integer | Sim | O id do upload. | ### Exemplo de requisição ```bash curl -X POST "https://api.hillsmusic.com/v1/ddex/uploads/312/commit" \ -H "Authorization: Bearer $HILLS_API_KEY" ``` ### Resposta `202` ```json { "data": { "id": 312, "status": "queued", "environment": "production", "status_url": "/v1/ddex/312" } } ``` ### Erros | Status | Quando | | --- | --- | | 401 | unauthenticated, invalid_key, key_revoked, key_expired ou test_keys_retired. | | 403 | insufficient_scope: falta à chave o escopo; scope indica qual. account_inactive ou api_not_in_plan. | | 404 | not_found: não existe, ou não é seu. | | 409 | upload_incomplete: partes ausentes ou com tamanho errado (missing e wrong_size as listam). already_committed: confirmado antes (status_url aponta para a entrega). commit_in_progress: outra confirmação deste upload está em andamento. | | 429 | rate_limited: aguarde Retry-After segundos. | ## Status da entrega `GET /v1/ddex/{id}` · Escopo: `ddex:write` ou `ddex:validate` queued → parsing → validating → importing → done / partial / failed, com um item por lançamento (criado, atualizado, sinalizado para a equipe, deixado de fora, teste) e cada erro com o seu campo DDEX. GET /ddex lista as suas últimas 100. ### Parâmetros | Parâmetro | Em | Tipo | Obrigatório | Descrição | | --- | --- | --- | --- | --- | | `id` | path | integer | Sim | O id da entrega (de POST /ddex ou da confirmação). | ### Exemplo de requisição ```bash curl "https://api.hillsmusic.com/v1/ddex/311" \ -H "Authorization: Bearer $HILLS_API_KEY" ``` ### Resposta `200` ```json { "data": { "id": 311, "member_id": 41, "environment": "production", "status": "partial", "message_id": "MSG-2026-0001", "ern_version": "4.3", "created_count": 1, "left_out_count": 1, "items": [ { "ref": "R0", "title": "Midnight Run", "upc": "0602600000017", "outcome": "created", "release_id": 912, "errors": [] } ] } } ``` ### Erros | Status | Quando | | --- | --- | | 401 | unauthenticated, invalid_key, key_revoked, key_expired ou test_keys_retired. | | 403 | insufficient_scope: falta à chave o escopo; scope indica qual. account_inactive ou api_not_in_plan. | | 404 | not_found: não existe, ou não é seu. | | 429 | rate_limited: aguarde Retry-After segundos. | Fonte: https://developer.hillsmusic.com/pt/reference/ddex-deliveries/