DataBolsa docs
Referência da APIDados de mercadoObjects

COMO dois objetos se ligam — descobre a cadeia, não a percorre

Para a pergunta de quem viu dois objetos no mesmo lugar e não sabe por quê: 'como esta empresa se liga a este fundo'. Diferente de `traverseObjectPath`, que percorre uma cadeia que VOCÊ especifica — aqui a cadeia é o que se descobre. Agrupado por cadeia, com `paths` dizendo quantos caminhos a sustentam e `examples` trazendo intermediários concretos: a Petrobras chega ao IPCA por 10 debêntures, e dez linhas iguais seriam despejo em vez de resposta. Cadeias mais curtas vêm primeiro. `max_hops` é 2 por default. O terceiro salto é CARO (segundos) e o quarto não existe de propósito: com grau médio alto ele liga quase tudo a quase tudo, e caminho que sempre existe não é evidência de nada. A direção da aresta é ignorada na busca e anotada em cada salto (`:out` = o objeto anterior pratica o verbo). `path_count` conta CAMINHOS DISTINTOS — sequências de objetos —, não linhas de aresta: a mesma ligação afirmada por duas fontes é um caminho, e contá-la duas vezes transformava redundância de fonte em argumento de robustez. Nenhum intermediário repete, nem volta para a origem ou o destino.

GET
/v1/objects/paths
AuthorizationBearer <token>

In: header

Query Parameters

from_idstring
to_idstring
max_hops?integer
Default2
Range1 <= value <= 3
limit?integer
Default10
Range1 <= value <= 25
at?string

Recorta CADA salto pela data. Sem ele a ligação pode ser inteiramente histórica — dois objetos que se cruzaram em 2019 e nunca mais.

A CADEIA É DESCOBERTA, então esta rota não recusa a pergunta datada como as irmãs fazem: não há verbo preso para recusar. Com at no passado, aresta de forma static (gestor, custodiante, auditor, sócio) sai da busca — devolvê-la apresentaria o estado de hoje como caminho daquela data — e meta.excluded_shapes diz que saiu. Caminho composto só de event/snapshot continua respondendo normalmente.

Corte temporal (AAAA-MM-DD). SEM ele a resposta é 'quem JÁ se relacionou', não 'quem se relaciona' — a diferença é grande e silenciosa.

O RECORTE DEPENDE DA FORMA DO VERBO (shape, publicado em listObjectRelations):

  • event (issued, indexed_to, succeeded_by): aconteceu numa data e não deixa de ter acontecido — entra tudo que ocorreu até at, sem limite superior. Aresta sem data declarada NÃO entra: o registro de ações não publica data de emissão, e afirmar que ela já existia numa data passada é afirmação que a fonte não faz.
  • snapshot (holds, contains, assigned_to, exposed_to_issuer): retrato por competência, e nenhum retrato se afirma válido depois de ser tirado. A janela é contida (relação que saiu e voltou não aparece no buraco), e at mais recente que a última competência recua até ela — a resposta diz em meta.as_of qual data foi realmente aplicada. Cada verbo tem a competência DELE: holds fecha no trimestre da CDA, contains no pregão do dia.
  • static (manages, administers, custodies, audits, same_owner, shareholder_of, measures, forecasts): o registro publica só o VIGENTE — 111.729 arestas sem início declarado. Com o verbo preso em rel, at no passado responde 400 em vez de devolver o gestor de hoje como gestor de 2020. Sem verbo preso, essas arestas são removidas do conjunto e meta.excluded_shapes diz que foram.

AS IRMÃS NÃO COMPARTILHAM O DEFAULT. Sem at: esta operação, listGlobalLinks, intersectObjects e findObjectPaths respondem 'quem JÁ se relacionou'; getObjectLinkStats resume o retrato VIGENTE (última competência do próprio conjunto); traverseObjectPath atravessa o retrato vigente POR SUJEITO em cada salto. As diferenças são deliberadas — histórico acumulado, resumo e travessia respondem perguntas distintas — e cada rota declara a sua no próprio at. Medido em 23/08/2026: 1 aresta no resumo contra 100+ na listagem, para o mesmo objeto, os dois certos.

Match^\d{4}-\d{2}-\d{2}$
resolve?string

Como interpretar o id recebido.

  • auto (default) — como REFERÊNCIA publicada: id fundido resolve sozinho para o sucessor (com redirected_from preenchido) e id cindido responde 409 com a lista.
  • exact — como o id do objeto que existe HOJE: nenhum histórico é consultado, e o id ou responde ou é 404.

Quando você precisa de exact: numa cisão, um dos sucessores é o PRÓPRIO id pedido — o ramo que ficou com a chave de nascimento herda o identificador. O 409 manda consultar cada sucessor, e consultar esse cairia no mesmo 409. exact é o endereço dele. Serve também para desligar o redirect automático de fusão quando você quer saber se o id que guardou ainda é o id de alguma coisa.

Default"auto"
Value in"auto" | "exact"

Response Body

curl -X GET "https://api.databolsa.com/v1/objects/paths?from_id=string&to_id=string&max_hops=2&limit=10&at=string&resolve=auto"
{
  "data": [
    {
      "hops": 0,
      "chain": "string",
      "path_count": 0,
      "paths": 0,
      "examples": [
        "string"
      ]
    }
  ],
  "meta": {
    "at": "string",
    "as_of": "string",
    "as_of_by_rel": {
      "property1": "string",
      "property2": "string"
    },
    "excluded_shapes": [
      "event"
    ]
  }
}
{
  "type": "string",
  "title": "string",
  "status": 0,
  "detail": "string",
  "instance": "string"
}

Resume uma coorte — soma, média ou mediana, repartida por propriedade ou relação

A outra metade de `rankObjects`. Aquele responde QUEM se destaca; este responde QUANTO DÁ, repartido. "O patrimônio dos FIDCs somado por gestora" não tinha caminho: a saída era paginar o ranking inteiro e agrupar no cliente, o que só funciona se a coorte couber na página. **A COORTE é a mesma de `rankObjects`** — `kind`, `subkind`, `rel`/`rel_to` e `where`, com a mesma sintaxe e o mesmo significado. Troque `rankObjects` por `aggregateObjects` na mesma consulta e você resume exatamente o conjunto que ordenaria. **`group_by` aceita PROPRIEDADE ou RELAÇÃO**, e a resposta diz qual em `meta.group_by_kind`. `group_by=situation` reparte por atributo; `group_by=manages` reparte pelo objeto do outro lado da aresta — e aí cada grupo traz `entity_id`, porque gestora é objeto. Quando o grupo é palavra, `entity_id` vem nulo: é assim que se distingue, e o formato da linha nunca muda. `meta.groupable` lista, na própria resposta, o que cabe aqui. **`group_by_direction` diz onde a COORTE está na aresta**, igual a `rel_direction`. `manages` liga gestora a fundo, então uma coorte de fundos está na ponta de ENTRADA (`in`). Errar a direção devolve lista vazia — e nesse caso `meta.empty_reason` diz qual direção funcionaria, em vez de deixar a resposta parecer "não há dado". **`sum` é RECUSADO em percentual, razão, múltiplo e ponto de índice.** Somar o dividend yield de 300 FIIs devolve um número, responde 200 e não significa nada. `avg`, `median`, `min` e `max` valem para qualquer unidade — a média de um percentual é um percentual. **Três números de cobertura, e eles não são detalhe.** `cohort_objects` é a coorte inteira e `cohort_with_value` o subconjunto que tem número na medida — este segundo é o que `rankObjects` chama de `cohort_size`, e os nomes diferem de propósito para que ninguém leia um pelo outro. `ungrouped` conta quem ficou FORA de todo grupo (medido: 20.098 dos 57.090 fundos não declaram situação), e sem ele o total dos grupos parece completo sendo parcial. `multi_group` conta quem caiu em MAIS DE UM grupo: zero num verbo funcional, grande em `issued`, onde o mesmo objeto entra numa vez por emissão e o `sum` o conta várias — o número não fica errado, a leitura muda. Cada grupo traz `objects` e `with_value`. Diferença entre os dois é cobertura parcial: um grupo com 36 objetos e nenhum valor devolve `value: null`, nunca zero. **Para o TOTAL do mercado, leia `meta.cohort_value` — não some a página.** É a mesma agregação aplicada à coorte inteira, antes de repartir: inclui os `ungrouped` e não depende do `limit`. O `group_by` continua obrigatório, mas deixou de ser o único caminho até o total. **`order_by=objects` ordena pelos grupos MAIORES em objetos** — "as gestoras com mais fundos" é essa pergunta. O default `value` ordena pela agregação, e com o teto de grupos as duas ordens podem devolver PÁGINAS diferentes. **Sem `fact`, com `agg=count`, a operação vira CENSO**: conta OBJETOS por grupo. É o único caminho de contagem para tipo que só tem propriedades — "quantas assessorias ativas por UF" é `kind=service_provider&agg=count&group_by=advisor_state&where=advisor_situation=EM FUNCIONAMENTO NORMAL`, sem medida nenhuma envolvida. `meta.fact` volta nulo e `value` = `objects`.

O objeto, seus apelidos e o MAPA do que dá para perguntar em seguida

`keys` traz todos os identificadores que apontam para o mesmo objeto — é o que responde 'PETR3 e PETR4 são a mesma empresa?'. `links` é o mapa: quais relações existem para ESTE objeto, em que direção e quantas. Relação que não existe não aparece, em vez de devolver página vazia numa travessia — página vazia, para quem consulta, é a afirmação de que não há relação. **ID QUE SAIU DE CIRCULAÇÃO NÃO É 404.** Objeto se funde e se cinde — raramente, mas acontece. Com sucessor ÚNICO (fusão) esta rota resolve sozinha e devolve o objeto atual com `redirected_from` preenchido: atualize o id que você guardou. Com mais de um sucessor (cisão) responde **409** listando todos, porque escolher um por você acertaria parte das vezes e erraria o resto em silêncio. Vale igual em `listObjectLinks`, `getObjectFacts`, `getObjectHistory`, `getObjectEvents`, `getObjectEvidence` e `findObjectPaths`. **A lista do 409 pode conter o próprio id que você pediu**: numa cisão, um dos ramos herda o identificador por continuidade técnica. Para ler ESSE ramo use `resolve=exact`, que lê o id literalmente — sem ele, consultar esse sucessor voltaria ao mesmo 409 e o ramo seria inalcançável por qualquer rota. Os demais respondem pelo id deles.