Versionamento e depreciação da API v1
Para quem integra com a API pública do BeryX: o que é estável, o que conta como quebra e como avisamos antes de mudar. Publicada no site em
/datavault/docs/versionamento-api; o resumo é a secção «Estabilidade» do portal (/datavault/developers#estabilidade, export emdocs/api/public/api-stability.json, gerado porbackend/scripts/api_portal.py— os prazos vêm do código). English version below.
1. O que está coberto
- O contrato é o spec público do portal (
/datavault/developers/openapi.jsonno site; cópia versionada em public/openapi.json): as operações de/api/v1que um token de APIdvk_*consegue chamar — os GET e as escritas explicitamente abertas a tokens (gate RAG, disparo de scans, runs de orquestradores, data-diff e decisão de confiança em lote) —, com os parâmetros, os schemas de pedido e de resposta, os códigos de estado e os headers que lá estão documentados. - O que não está no portal não tem garantias e pode mudar sem aviso: os endpoints que só a app
web usa (sessão de utilizador), a administração da conta, dos tokens e da faturação, a consola
BeryxTech, o chat e os streams da UI, e o
/openapi.jsoncompleto que a app serve fora de produção. - Texto não é contrato: descrições, resumos, exemplos e as mensagens legíveis dos erros
(
message,detailem texto) podem mudar em qualquer versão. O que é contrato é ocode.
2. Versões
- A API tem semver próprio, separado da versão do produto; a regra (minor = adições
compatíveis, major = quebra anunciada) e a razão de ser separada estão em
PRODUTO.md §8 — esta política aplica-a, não a
redefine. A versão em vigor é a entrada mais recente de changelog.json e sai em
GET /api/v1/versioneGET /api/v1/health(api_version) e noinfo.versiondo spec. - Patch (
X.Y.z): correções que repõem o comportamento documentado. - Minor (
X.y.0): só adições (§3). - Major (
X.0.0): quebras (§4), sempre depois de uma depreciação (§5). - O prefixo
/api/v1não acompanha o semver: uma major pode retirar o que foi depreciado sem mudar de prefixo. Se um dia existir/api/v2, o/api/v1continua a responder pelo menos durante a janela de depreciação.
3. Mudanças compatíveis (minor)
Uma versão minor só acrescenta:
- operações novas, parâmetros opcionais novos e headers de resposta novos;
- campos novos nas respostas — o teu cliente deve ignorar campos que não conhece (o SDK Python já o faz);
- valores novos em enums de resposta — trata um valor desconhecido como «outro» em vez de falhar;
codenovos (razões, bloqueadores, erros).
code estáveis. Os code das razões da decisão de confiança
(GET /datasets/{dataset_id}/trust-decision), dos bloqueadores e avisos da readiness
(GET /domains/{domain_id}/readiness) e dos erros com detail = {code, message} são estáveis: o
mesmo code quer sempre dizer o mesmo; só o texto pode mudar.
Envelopes com schema_version — os factos de confiança (trust-facts.md) e os
feeds de BI: campos novos só no fim; o schema_version só sobe numa quebra, e essa quebra segue
esta política.
4. O que é uma quebra (major)
- remover ou renomear uma operação, um parâmetro, um campo ou um valor de enum;
- mudar o tipo ou o formato de um campo ou parâmetro (ex.:
string→integer, data → data-hora); - tornar obrigatório um parâmetro ou campo de pedido que era opcional, ou apertar a validação de modo que um pedido antes aceite passe a ser recusado (limites menores, padrões mais estritos);
- mudar o significado de um campo, de um
codeou do estado HTTP de uma situação (ex.:404→403); - baixar o máximo de
limitou mudar a ordenação por omissão de uma listagem; - passar a exigir autenticação numa operação pública, ou retirar a um token uma operação que ele podia chamar.
Uma quebra só sai de duas formas: numa versão de caminho nova (/api/v2, §2), com /api/v1 sem
mudanças, ou numa versão major depois do processo de depreciação (§5).
Exceção de segurança. Se manter um comportamento expõe dados ou permite abuso, podemos mudá-lo
sem janela. Fica no changelog com o tipo security e é comunicado aos admins dos workspaces com
tokens de API ativos.
O que o CI verifica. api_portal.py build --check falha se o export do portal não
corresponder às rotas. api_portal.py guard compara o contrato com o da base e classifica cada
diferença em compatível ou quebra (backend/app/domain/api_contract/diff.py, cartão #367):
remoções, tipos e formatos mudados, campos de resposta que podem vir null, pedidos que passam a
obrigatórios, valores de enum removidos, validação mais estrita, valores por omissão mudados,
códigos de estado removidos e autenticação nova. Falha se o contrato mudar sem uma versão nova no
topo do changelog, e se uma quebra não vier numa major (ou com uma entrada security), listada em
docs/api/BREAKING.md e, num PR, com o label api-breaking. Uma mudança de significado (de um
campo, de um code ou de um estado HTTP) não se vê no spec e fica para a revisão.
5. Depreciação
Anúncio no changelog — entrada do tipo
deprecatednuma versão minor, com o que é depreciado, a alternativa e a data de fim.Anúncio nas respostas — a operação passa a
deprecated: trueno spec e responde com (helperdeprecate()emapp/api/deps.py):Deprecation: @<segundos desde a época>(RFC 9745) — desde quando está depreciada;Sunset: <data HTTP>(RFC 8594) — a partir de quando deixa de responder;Link: <url da nota de migração>; rel="deprecation"; type="text/html"(RFC 9745).
Deprecation: @1790812800 Sunset: Thu, 01 Apr 2027 00:00:00 GMT Link: <https://praxis.lbostuff.tech/datavault/developers#estabilidade>; rel="deprecation"; type="text/html"O CORS expõe os três headers, por isso um cliente no browser também os vê.
Janela mínima de 180 dias entre o anúncio e o
Sunset(odeprecate()recusa uma janela menor). Durante a janela a operação continua a responder como antes.Comunicação direta aos admins dos workspaces com tokens de API ativos, no anúncio e antes do fim.
Fim — no
Sunset, a remoção sai numa major, com uma entradaremovedno changelog.
6. SDK
O SDK Python (beryx-sdk, sdk/README.md) tem versões e tags próprias
(sdk-v*). Suportamos as duas minor mais recentes (N e N-1): recebem correções e acompanham a
API. Versões mais antigas continuam a funcionar enquanto a API não tiver quebras — os tipos do SDK
toleram campos novos —, mas sem correções. Uma depreciação na API que afete o SDK sai numa minor
do SDK dentro da janela de 180 dias.
7. Rate limits e quotas
- Cada token tem um limite de pedidos próprio, além do limite por IP. Os valores em vigor vêm nas
respostas (
X-RateLimit-Limit,X-RateLimit-Remaining,X-RateLimit-Reset; os endpoints de saúde estão isentos); acima do limite a API responde429comRetry-After(segundos). Os valores são configuração do serviço (app/api/ratelimit.py), não contrato fixo. - As quotas do plano (fontes, datasets, scans e relatórios por mês) estão na página de preços e no
catálogo de planos (
app/domain/billing/plans.py); acima de uma quota a API responde402com{detail, plan, limit}. - Os limites e as quotas podem mudar: um aumento aplica-se logo; uma redução é anunciada com pelo menos 30 dias de antecedência (changelog e comunicação aos admins), exceto medidas contra abuso, que podem ser imediatas.
8. Reportar um problema
- Uma resposta que contradiga o contrato é um bug nosso. Escreve para suporte@praxis.lbostuff.tech (assunto
«API») com o método e o caminho, o estado HTTP, a hora (UTC), o
X-Request-IDda resposta (nos erros vem também emrequest_id) e a resposta deGET /api/v1/version(version,build_sha,api_version). Nunca envies o token; se o expuseste, revoga-o em Definições → Tokens de API. - Corrigimos o comportamento para cumprir o contrato (patch, tipo
fixed); se o erro estava no contrato, a correção segue esta política. - Vulnerabilidades: o contacto em
/.well-known/security.txt(SEGURANCA.md).
Para quem mantém a API
- Mudaste algo no spec público?
python scripts/api_portal.py diff(compara com o export versionado e classifica cada diferença embreakingoucompatible) → entrada nova no topo de changelog.json →API_VERSIONembackend/app/version.py→make openapina raiz (o mesmo quepython scripts/api_portal.py build, regeneradocs/api/public/) → commit. No CI corrembuild --checkeguard. Uma quebra pede ainda a versão major, a secção dessa versão emdocs/api/BREAKING.mdcom cada rota partida entre crases e o labelapi-breakingno PR. - Depreciar:
deprecated=Truena rota,deprecate(response, sunset, link, since=…)no endpoint e a entradadeprecatedno changelog. - O praxis-site copia
docs/api/public/paracontent/developers/e este documento paracontent/docs/api/(pnpm sync:docs). Opnpm builddo site correscripts/check_developers.mjs: valida a cópia (versão do spec = topo do changelog, secções pt/en, política publicada com os mesmos prazos) e, comPRAXIS_PRODUTO_DIR, recusa-a se não for igual, byte a byte, adocs/api/public/. - Uma operação pública nova responde com um modelo
*Out(response_model=), nunca com um-> dictsem schema: oguardnão vê dentro de uma resposta sem schema, por isso não dá por um campo removido.backend/tests/test_api_untyped_ratchet.pychumba a operação nova. As que ainda não têm schema estão embackend/tests/api_untyped_allowlist.json, e essa lista só encolhe. O modelo declara todas as chaves que odictdevolve, porque oresponse_modelcorta as que não conhece.
English
For those integrating with the BeryX public API: what is stable, what counts as a breaking change and how we warn before changing. The summary of this policy is the «Stability» section of the
/datavault/developersportal (/datavault/developers#estabilidade).
1. What is covered
- The contract is the portal's public spec (
/datavault/developers/openapi.json): the/api/v1operations an API tokendvk_*can call — the GETs and the writes explicitly open to tokens (RAG gate, triggering scans, orchestrator runs, data-diff and batch trust decisions) — with the parameters, request and response schemas, status codes and headers documented there. - Whatever is not in the portal has no guarantees and may change without notice: endpoints only
the web app uses, account, token and billing administration, the BeryxTech console, chat and UI
streams, and the full
/openapi.jsonserved outside production. - Text is not contract: descriptions, summaries, examples and human-readable error messages may
change in any version. The
codeis the contract.
2. Versions
- The API has its own semver, separate from the product version (rule and rationale in
PRODUTO.md §8: minor = compatible additions, major = announced breaking change). The version in
force is the latest entry of the API changelog and is returned by
GET /api/v1/version,GET /api/v1/health(api_version) and the spec'sinfo.version. - Patch: fixes that restore documented behaviour. Minor: additions only. Major: breaking changes, always after a deprecation.
- The
/api/v1prefix does not follow semver: a major may drop what was deprecated without changing prefix. If an/api/v2ever exists,/api/v1keeps responding at least during the deprecation window.
3. Compatible changes (minor)
New operations, optional parameters, response headers, response fields (ignore fields you do not
know), enum values (handle unknown values) and new codes. The codes of trust-decision
reasons, readiness blockers and warnings, and errors with detail = {code, message} are stable.
Envelopes with schema_version (trust facts, BI feeds) add fields only at the end and only bump
schema_version in a breaking change.
4. What a breaking change is (major)
Removing or renaming an operation, parameter, field or enum value; changing a type or format;
making something optional required or rejecting a request that used to be accepted; changing the
meaning of a field, a code or an HTTP status; lowering the maximum limit or changing a listing's
default order; requiring authentication on a public operation or taking an operation away from
tokens. Breaking changes only ship in one of two ways: under a new path version (/api/v2),
leaving /api/v1 unchanged, or in a major after deprecation. Security exception: if keeping
a behaviour exposes data or enables abuse we may change it without a window, logged with type
security. CI compares the contract with the base and classifies every difference as compatible
or breaking. It fails when the public contract changes without a new changelog version, and when a
breaking change is not in a major (or a security entry), listed in docs/api/BREAKING.md and,
on a pull request, labelled api-breaking. A change of meaning does not show in the spec and is
left to review.
5. Deprecation
- A
deprecatedentry in the changelog (minor version) with what is deprecated, the alternative and the end date. - The operation is marked
deprecated: truein the spec and responds withDeprecation(RFC 9745),Sunset(RFC 8594) andLinkwithrel="deprecation"pointing to the migration note. CORS exposes the three headers. - At least 180 days between the announcement and
Sunset; the operation keeps working during the window. - Direct communication to the admins of workspaces with active API tokens, at the announcement and before the end.
- At
Sunset, the removal ships in a major with aremovedchangelog entry.
6. SDK
The Python SDK (beryx-sdk) has its own versions (sdk-v* tags). We support the two most
recent minors (N and N-1): they get fixes and track the API. Older versions keep working while the
API has no breaking changes, but get no fixes.
7. Rate limits and quotas
Per-token and per-IP request limits are reported in X-RateLimit-Limit, X-RateLimit-Remaining
and X-RateLimit-Reset; above the limit the API responds 429 with Retry-After. Plan quotas are
on the pricing page; above a quota the API responds 402. Limits and quotas may change: an
increase applies at once; a reduction is announced at least 30 days in advance, except
anti-abuse measures.
8. Reporting a problem
Write to suporte@praxis.lbostuff.tech (subject «API») with the method and path, HTTP status, time (UTC), the
X-Request-ID of the response (errors also carry it in request_id) and the response of GET /api/v1/version —
never the token. Vulnerabilities: the contact in
/.well-known/security.txt.