Referência da API

Tudo o que a API pública aceita.

Endpoints, autenticação, paginação, ordenação e a DSL completa de filtros do GET — com exemplos em cURL, SDK JavaScript e fetch.

Começando

Visão geral

Toda a API pública vive sob um único formato de endereço. O slug identifica o projeto e o namespace agrupa registros — ele é criado automaticamente no primeiro POST.

GET/api/v1/{slug}/{namespace}
ElementoRegras
slugMinúsculas, números e hífen. Definido na criação do projeto e imutável.
namespaceDe 1 a 64 caracteres: letras, números, hífen e underscore. Normalizado para minúsculas. Nomes reservados (admin, system, __proto__) são recusados com 400 INVALID_NAMESPACE.
Content-Typeapplication/json em POST, PUT e PATCH.
X-Request-IdDevolvido em toda resposta. Envie o seu para correlacionar logs.
Corpo aceitoQualquer JSON válido — objeto, array, string, número, booleano ou null. Não há schema para declarar.

Autenticação

Cada projeto usa Basic, OAuth 2.0 ou ambos. O projeto autenticado precisa ser exatamente o projeto do slug na URL — caso contrário a resposta é 403 CLIENT_MISMATCH.

# O par usuario:senha e enviado em Base64.
curl 'https://api.jsondock.catini.org/api/v1/meu-projeto/produtos' \
  -H "Authorization: Basic $(printf '%s' 'usuario:senha' | base64)"
Escopo OAuthLibera
records:readGET (lista e item individual)
records:writePOST, PUT, PATCH
records:deleteDELETE (exclusão lógica)

Credenciais Basic recebem os três escopos implicitamente — a granularidade por escopo é um recurso do OAuth 2.0.

Nunca exponha Basic no navegadorEm um site público, use um backend próprio ou tokens Bearer de curta duração. A senha Basic aparece uma única vez, na criação ou na rotação.

Envelope de resposta

Seu JSON fica sempre dentro de data. Os campos ao redor são gerenciados pela plataforma — se você enviar chaves com esses nomes, elas permanecem dentro de data e nunca sobrescrevem o controle interno.

{
  "id": "665f1f77bcf86cd799439011",
  "client": "meu-projeto",
  "namespace": "produtos",
  "data": { "nome": "Notebook", "preco": 4500 },
  "version": 1,
  "createdAt": "2026-07-20T10:00:00.000Z",
  "updatedAt": "2026-07-20T10:00:00.000Z"
}

Endpoints

Resumo

POST/api/v1/{slug}/{namespace}201 · cria
GET/api/v1/{slug}/{namespace}200 · lista
GET/api/v1/{slug}/{namespace}/{id}200 · consulta
PUT/api/v1/{slug}/{namespace}/{id}200 · substitui
PATCH/api/v1/{slug}/{namespace}/{id}200 · mescla
DELETE/api/v1/{slug}/{namespace}/{id}204 · exclusão lógica
PUT e PATCH incrementam version. A exclusão permanente não existe na API pública: fica restrita ao painel administrativo, com auditoria.

Criar registro

POST/api/v1/{slug}/{namespace}
curl -X POST 'https://api.jsondock.catini.org/api/v1/meu-projeto/produtos' \
  -H "Authorization: Basic $(printf '%s' 'usuario:senha' | base64)" \
  -H 'Content-Type: application/json' \
  -d '{"nome":"Teclado mecanico","preco":349.9,"estoque":12,"ativo":true}'

Listar registros

GET/api/v1/{slug}/{namespace}

O GET de lista aceita paginação, ordenação, janelas de data e a DSL de filtros. Todos os parâmetros são opcionais e podem ser combinados livremente.

curl -G 'https://api.jsondock.catini.org/api/v1/meu-projeto/produtos' \
  -H "Authorization: Basic $(printf '%s' 'usuario:senha' | base64)" \
  --data-urlencode 'page=1' \
  --data-urlencode 'limit=20' \
  --data-urlencode 'sort=createdAt' \
  --data-urlencode 'direction=desc' \
  --data-urlencode 'filter[ativo][eq]=true' \
  --data-urlencode 'filter[preco][lte]=500'

Obter por ID

GET/api/v1/{slug}/{namespace}/{id}
curl 'https://api.jsondock.catini.org/api/v1/meu-projeto/produtos/665f1f77bcf86cd799439011' \
  -H "Authorization: Basic $(printf '%s' 'usuario:senha' | base64)"

ID fora do formato ObjectId responde 400 INVALID_OBJECT_ID; ID válido inexistente responde 404 RECORD_NOT_FOUND.

Substituir (PUT)

PUT/api/v1/{slug}/{namespace}/{id}

Troca data integralmente. O que não estiver no corpo desaparece.

curl -X PUT 'https://api.jsondock.catini.org/api/v1/meu-projeto/produtos/665f1f77bcf86cd799439011' \
  -H "Authorization: Basic $(printf '%s' 'usuario:senha' | base64)" \
  -H 'Content-Type: application/json' \
  -d '{"nome":"Teclado mecanico RGB","preco":399.9}'

Atualizar (PATCH)

PATCH/api/v1/{slug}/{namespace}/{id}
curl -X PATCH 'https://api.jsondock.catini.org/api/v1/meu-projeto/produtos/665f1f77bcf86cd799439011' \
  -H "Authorization: Basic $(printf '%s' 'usuario:senha' | base64)" \
  -H 'Content-Type: application/json' \
  -d '{"preco":329.9,"desconto":null}'

Excluir

DELETE/api/v1/{slug}/{namespace}/{id}
curl -X DELETE 'https://api.jsondock.catini.org/api/v1/meu-projeto/produtos/665f1f77bcf86cd799439011' \
  -H "Authorization: Basic $(printf '%s' 'usuario:senha' | base64)"

Responde 204 sem corpo. A exclusão é lógica: o registro some das consultas públicas, mas permanece recuperável pelo painel.

Consultas no GET

Paginação

ParâmetroPadrãoRegras
page1Inteiro ≥ 1.
limit20Inteiro de 1 a 100. Não existe consulta sem limite.
?page=1&limit=20
?page=3&limit=100   # maximo permitido
?limit=101          # 400 VALIDATION_ERROR

Ordenação

ParâmetroPadrãoValores aceitos
sortcreatedAtcreatedAt, updatedAt, version
directiondescasc, desc
Não é possível ordenar por campos de dataA ordenação usa apenas os campos da plataforma. Propriedades dentro de data não são ordenáveis pela API — filtre pela API e ordene o resultado na sua aplicação.
?sort=createdAt&direction=desc   # mais recentes primeiro (padrao)
?sort=updatedAt&direction=desc   # ultimos alterados
?sort=version&direction=desc     # mais editados
?sort=preco                      # 400 VALIDATION_ERROR

Filtros por data

Quatro parâmetros filtram pelas datas gerenciadas pela plataforma. Todos esperam ISO 8601 e são inclusivos nas extremidades.

ParâmetroEfeito
createdAfterCriados a partir da data informada.
createdBeforeCriados até a data informada.
updatedAfterAlterados a partir da data informada.
updatedBeforeAlterados até a data informada.
# Janela por data de criacao e de atualizacao (ISO 8601).
curl -G 'https://api.jsondock.catini.org/api/v1/meu-projeto/pedidos' \
  -H "Authorization: Basic $(printf '%s' 'usuario:senha' | base64)" \
  --data-urlencode 'createdAfter=2026-01-01T00:00:00.000Z' \
  --data-urlencode 'createdBefore=2026-02-01T00:00:00.000Z'

Filtros em data

Para consultar qualquer propriedade do seu JSON, a API usa uma DSL própria no formato:

filter[caminho][operador]=valor

O caminho é a propriedade dentro de data (sem escrever data.), o operador é um dos nove suportados e o valor é sempre texto na URL — a conversão de tipo é automática.

Nenhum objeto do MongoDB é aceitoA DSL é traduzida no servidor para uma consulta restrita ao campo data. Operadores arbitrários, JavaScript executável e sintaxe de regex do consumidor nunca chegam ao banco.

Operadores

São nove operadores. Qualquer outro nome responde 400 INVALID_FILTER listando os válidos.

eqIgual a
filter[status][eq]=aprovado

Igualdade exata. Aceita texto, numero, booleano e null.

neDiferente de
filter[status][ne]=cancelado

Registros cujo valor e diferente. Documentos sem a propriedade tambem entram.

gtMaior que
filter[preco][gt]=1000

Comparacao numerica ou lexicografica (texto e datas ISO 8601).

gteMaior ou igual
filter[preco][gte]=1000

Idem gt, incluindo o limite.

ltMenor que
filter[estoque][lt]=5

Idem gt, na direcao oposta.

lteMenor ou igual
filter[estoque][lte]=5

Idem lt, incluindo o limite.

inPertence a lista
filter[categoria][in]=perifericos,monitores

Lista separada por virgula. Espacos ao redor sao removidos. Maximo de 25 valores.

existsPropriedade existe
filter[desconto][exists]=true

true retorna quem tem a propriedade; false retorna quem nao tem. Qualquer valor diferente de "false" e tratado como true.

containsContem o texto
filter[nome][contains]=teclado

Substring, sem diferenciar maiusculas. O valor e 100% escapado — nenhuma sintaxe de regex do consumidor e executada.

Tudo junto
# Produtos ativos, acima de R$ 1.000, da categoria perifericos,
# com "mecanico" no nome e que possuam a propriedade garantia.
curl -G 'https://api.jsondock.catini.org/api/v1/meu-projeto/produtos' \
  -H "Authorization: Basic $(printf '%s' 'usuario:senha' | base64)" \
  --data-urlencode 'filter[ativo][eq]=true' \
  --data-urlencode 'filter[preco][gte]=1000' \
  --data-urlencode 'filter[categoria][in]=perifericos,monitores' \
  --data-urlencode 'filter[nome][contains]=mecanico' \
  --data-urlencode 'filter[garantia][exists]=true'

Combinando filtros

# Todos os filtros sao combinados com AND.
?filter[ativo][eq]=true&filter[categoria][eq]=perifericos

# Resultado: ativo = true E categoria = perifericos

Caminhos aninhados e arrays

Use ponto para descer na estrutura, até 6 níveis. Em arrays, a condição casa se qualquer item satisfizer o filtro.

{
  "nome": "Notebook",
  "preco": 4500,
  "fornecedor": {
    "nome": "XPTO Distribuidora",
    "endereco": { "cidade": "Recife", "uf": "PE" }
  },
  "tags": ["promocao", "black-friday"]
}

Conversão de tipos

O valor sempre chega como texto na query string. A API converte antes de consultar, seguindo regras fixas:

Valor na URLViraTipo
truetruebooleano
falsefalsebooleano
nullnullnulo
45004500número
349.9349.9número
-10-10número
2026-07-20"2026-07-20"texto
012341234número — cuidado com CEP, CPF e códigos com zero à esquerda
Números com zero à esquerdaUm valor como 01234 é convertido para o número 1234 e não encontra o texto "01234". Para códigos desse tipo, use contains ou grave o valor já como número.

Os operadores gt, gte, lt e lte aceitam apenas números e textos. Um booleano ou null nessas comparações responde 400 INVALID_FILTER.

Limites e recusas

RegraLimite
Filtros por consulta10
Profundidade do caminho6 níveis
Tamanho do caminho128 caracteres
Tamanho de cada segmento64 caracteres
Tamanho do valor512 caracteres
Valores em in25

Rejeitado com 400 INVALID_FILTER

SituaçãoExemplo
Operador desconhecidofilter[nome][like]=teclado
JavaScript executável ou operador do Mongofilter[$where][eq]=...
Poluição de protótipofilter[__proto__][eq]=x
Caractere inválido no caminhofilter[nome do produto][eq]=x
Filtro sem operadorfilter[nome]=teclado
in vazio ou contains vaziofilter[tag][in]=
Mais de 10 filtros, ou caminho/valor acima do limite
Custo de consultaOs filtros são sempre combinados com o projeto e o namespace, que são indexados. Propriedades dentro de data não têm índice — para volumes altos, prefira reduzir o conjunto por createdAfter antes de filtrar.

Referência

Limites de payload

LimiteValorErro
Profundidade do JSON32 níveis422 PAYLOAD_TOO_DEEP
Propriedades por objeto1000422 INVALID_JSON
Chaves __proto__, constructor, prototypeproibidas422 INVALID_JSON
Chaves iniciadas por $proibidas422 INVALID_JSON
Chaves contendo .proibidas422 INVALID_JSON
Tamanho do corpoconfigurado por projeto413 PAYLOAD_TOO_LARGE

Rate limit

O limite é aplicado por projeto autenticado. Toda resposta traz o estado atual da janela nos cabeçalhos:

CabeçalhoSignificado
RateLimit-LimitRequisições permitidas na janela.
RateLimit-RemainingQuantas ainda restam.
RateLimit-ResetSegundos até a janela reiniciar.

Projetos criados pelo cadastro gratuito começam com 180 requisições por minuto. A janela é de um minuto e o limite é contado por projeto, não por IP.

Ao estourar, a API responde 429 RATE_LIMIT_EXCEEDED. Trate o 429 com recuo exponencial respeitando RateLimit-Reset.

Códigos de erro

Todo erro usa o mesmo envelope, sempre com code estável e requestId para suporte.

{
  "statusCode": 400,
  "error": "Bad Request",
  "code": "INVALID_FILTER",
  "message": "Operador \"like\" nao suportado. Use: eq, ne, gt, gte, lt, lte, in, exists, contains.",
  "requestId": "01J8Z9K2M4N6P8Q0R2S4T6V8",
  "timestamp": "2026-07-20T10:00:00.000Z",
  "path": "/api/v1/meu-projeto/produtos"
}
StatusCódigoQuando acontece
400INVALID_FILTEROperador, caminho ou valor de filtro inválido.
400VALIDATION_ERRORParâmetro de paginação, ordenação ou data fora do aceito.
400INVALID_NAMESPACENamespace com formato inválido ou reservado.
400INVALID_OBJECT_IDID que não é um ObjectId válido.
401INVALID_CREDENTIALSUsuário ou senha Basic incorretos.
401INVALID_TOKENBearer expirado, malformado ou sem projeto correspondente.
403CLIENT_MISMATCHO projeto do token não é o projeto do slug na URL.
403INSUFFICIENT_SCOPEO token não tem o escopo exigido pela operação.
403CLIENT_INACTIVEProjeto inativo, bloqueado ou excluído.
404RECORD_NOT_FOUNDRegistro inexistente ou já excluído.
413PAYLOAD_TOO_LARGECorpo acima do limite do projeto.
422PAYLOAD_TOO_DEEPJSON com mais de 32 níveis.
422INVALID_JSONChave proibida ou objeto com propriedades demais.
429RATE_LIMIT_EXCEEDEDLimite de requisições estourado.
503SERVICE_UNAVAILABLEDependência indisponível no momento.

Pronto para testar?

Crie um projeto gratuito, copie as credenciais e faça a primeira chamada em menos de um minuto.