API do arvore.link
para automatizar o que faria na mão: criar e editar links curtos, montar árvores e ler seus próprios cliques. de graça, sem depender de plano pago para ter acesso.
índice e busca
comece aqui
- 1. crie sua conta — é só um código no e-mail, sem senha.
- 2. vá em painel → API e crie um token. ele aparece uma única vez: guardamos só um hash, então nem nós conseguimos mostrá-lo de novo.
- 3. mande o token no cabeçalho de cada requisição.
curl -X POST https://api.arvore.link/links \
-H "Authorization: Bearer arv_seu_token" \
-H "Content-Type: application/json" \
-d '{"url":"https://exemplo.com/uma-pagina"}'
# {"id":"a1b2c3d4","slug":"x7k2","short_url":"https://arvr.ink/x7k2", ...}autenticação
um token começa com arv_ e não expira. ele faz o que você faz com links, árvores e métricas — mas não administra a conta: trocar e-mail, apagar a conta, encerrar sessões e criar outros tokens respondem 403 e exigem login de verdade.
isso não é uma limitação por acaso: é o que faz a revogação valer. um token vazado não consegue criar um segundo token para sobreviver à revogação do primeiro.
limites
no plano gratuito: um token ativo por conta e 100 requisições por hora por token. passando disso, a resposta é 429 com {"error":"RATE_LIMITED"} e um cabeçalho Retry-After em segundos.
revogar um token libera a vaga, então trocar de token é revogar e criar — o registro do antigo continua na lista, com a data em que parou de valer.
parâmetros UTM
não existe um campo de UTM na API. os parâmetros fazem parte do próprio destino, então monte a url completa e mande em url:
curl -X POST https://api.arvore.link/links \
-H "Authorization: Bearer arv_..." \
-H "Content-Type: application/json" \
-d '{"url":"https://exemplo.com.br/promo?utm_source=instagram&utm_medium=social"}'é de propósito: guardar os parâmetros separados criaria duas versões da mesma informação, que podem discordar. o painel faz exatamente isso — junta tudo na url antes de enviar — e lê de volta a partir dela quando você abre o link para editar.
o campo de referral escreve ref, não utm_referral — esse último não é lido por nenhuma ferramenta de análise.
expiração
expires_at é em milissegundos, não em segundos. uma data no passado é recusada com EXPIRES_AT_IN_THE_PAST — quase sempre é erro de fuso, e aceitar criaria um link já morto.
curl -X PATCH https://api.arvore.link/links/a1b2c3d4 \
-H "Authorization: Bearer arv_..." \
-H "Content-Type: application/json" \
-d '{"expires_at":1785400000000,"expiration_url":"https://exemplo.com.br/acabou"}'depois da data, o link responde 302 para expiration_url, ou 404 se não houver um. é 302 e não 301 de propósito: um permanente fica no cache do navegador e continuaria valendo mesmo depois de você adiar ou remover a expiração. o clique continua sendo contado nos dois casos — tráfego numa campanha que acabou é justamente o que vale saber.
expiration_url sozinho é recusado com EXPIRATION_URL_WITHOUT_EXPIRY: sem data ele nunca seria usado.
no PATCH, todo campo opcional segue as mesmas três regras: omitir mantém o que está gravado, null apaga, e um valor grava. vale para expires_at, expiration_url e tags (que usa [] para apagar).
segmentação
um link, destinos diferentes por sistema operacional e por país:
curl -X PATCH https://api.arvore.link/links/a1b2c3d4 \
-H "Authorization: Bearer arv_..." \
-H "Content-Type: application/json" \
-d '{"targeting":{
"ios":"https://apps.apple.com/app/id123",
"android":"https://play.google.com/store/apps/details?id=x",
"geo":{"PT":"https://exemplo.pt"}
}}'o sistema operacional tem prioridade sobre o país. um iPhone no Brasil que casa com a regra de iOS e com a de BR vai para a App Store — a regra de país é a afirmação mais ampla, então ela perde. quem não casa com nenhuma regra vai para o url normal, que continua obrigatório.
a regra de ios vale também para iPadOS — mandar um iPad para a Play Store é exatamente o erro que essa função existe para evitar. os códigos de país são ISO 3166-1 alfa-2 e são gravados em maiúsculas, porque é assim que o CloudFront informa o país — uma chave minúscula seria uma regra que nunca casa. no máximo 50 países por link.
targeting é substituído por inteiro, não mesclado: mande o conjunto completo de regras, ou null para remover todas. mesclar tornaria impossível apagar um país, já que não haveria como dizer que ele não existe mais.
um link expirado ignora a segmentação: acabou para todo mundo. cada clique registra qual regra decidiu o destino, então /analytics responde se a segmentação está funcionando de verdade.
senha
um link com senha para de redirecionar direto: quem abrir vê um formulário e só depois é levado ao destino.
curl -X PATCH https://api.arvore.link/links/a1b2c3d4 \
-H "Authorization: Bearer arv_..." \
-H "Content-Type: application/json" \
-d '{"password":"verao2026"}'a senha nunca volta em nenhuma resposta e não pode ser lida depois. ela é gravada como um hash com salt (scrypt), e o que a API devolve é só has_password. se você precisa dela depois, guarde-a você mesmo — é a mesma propriedade dos tokens de API. mande null para remover.
o que ela protege, e o que não: um link curto é público, então a senha controla o acesso ao destino, não o esconde de quem já a tem — quem souber a senha pode repassá-la. use para conteúdo que não deve circular por acidente, não para segredo de verdade.
tentativas erradas são limitadas por endereço e por link. o clique só é contado depois que a senha passa — contar quem não entrou não responderia nada.
prévia ao compartilhar
normalmente o card que aparece no WhatsApp ou no LinkedIn vem do destino: o link curto responde 301, o rastreador segue e lê as tags de lá. definir og_title, og_description ou og_image muda isso.
curl -X PATCH https://api.arvore.link/links/a1b2c3d4 \
-H "Authorization: Bearer arv_..." \
-H "Content-Type: application/json" \
-d '{"og_title":"A promoção acaba domingo",
"og_description":"frete grátis em tudo",
"og_image":"https://exemplo.com.br/card.png"}'com qualquer um desses campos definido, o link passa a responder HTML com essas tags para rastreadores de redes sociais — Facebook, WhatsApp, X, LinkedIn, Slack, Telegram, Discord, iMessage. todo o resto continua recebendo 301, incluindo Google e Bing: um buscador que segue o redirecionamento credita o destino, e é isso que queremos.
é uma heurística baseada no User-Agent, então erra às vezes: um rastreador novo recebe o 301 e não mostra o card. o pior caso é um compartilhamento sem card, não um link quebrado.
og_image aceita qualquer URL http(s) — aponte para uma imagem que você já hospeda. não existe upload de arquivo na API pública, pelo mesmo motivo que upload de avatar também não: é um fluxo de painel, não de script. sem imagem mas com título, uma é gerada a partir dele.
um link expirado ignora o card: mostrar prévia de um link morto é pior do que não mostrar nenhuma. num link com senha, o rastreador vê o card e a pessoa vê o formulário — o card só contém o que você escreveu nele, então isso é justamente o motivo de usar os dois juntos.
denúncias
POST /reports sinaliza um link curto para análise. está na API de propósito: quem monitora abuso, protege uma marca ou mantém um feed de ameaças reporta em volume, e obrigar essa pessoa a engenharia reversa seria perverso.
curl -X POST https://api.arvore.link/reports \
-H "Content-Type: application/json" \
-d '{"url":"https://arvr.ink/a1b2","reason":"phishing",
"detail":"chegou por sms se passando pelo banco"}'uma denúncia não desativa nada. ela grava um registro que uma pessoa analisa. se bastasse denunciar para derrubar, qualquer um teria um botão para tirar o link do concorrente do ar — e abusar do sistema de denúncias seria mais fácil do que o abuso que ele previne.
não precisa de token, e um token não ajuda. quem recebeu um link de phishing não tem conta aqui. denúncias são julgadas pelo conteúdo, então quem se identifica não tem mais peso do que quem não se identifica, e os limites valem para os dois.
url precisa ser um link do domínio de redirecionamento — qualquer outra coisa responde 400 NOT_A_SHORT_LINK em vez de ser gravada, senão a fila vira um depósito que alguém tem que garimpar. um slug que não existe responde 200 e não grava nada: um 404 transformaria o endpoint em um oráculo de slugs.
dois limites: 10 por hora por endereço e 20 por hora por link denunciado. o segundo existe porque mil denúncias do mesmo link enterrariam todas as outras — é a negação de serviço contra a análise, não contra o site.
erros
todo erro vem como {"error":"CODIGO"} com um status HTTP coerente. error é sempre texto, nunca um objeto — dá para checar e ramificar sem inspecionar a estrutura. os mais comuns: UNAUTHORIZED (401), SESSION_REQUIRED (403), SLUG_ALREADY_IN_USE (409), RATE_LIMITED (429).
um 400 de validação traz também fields, com o que está errado em cada entrada — útil para apontar o campo num formulário: {"error":"VALIDATION_FAILED","fields":{"url":["Invalid URL"]}}. quando o schema tem um código próprio, ele vem no lugar de VALIDATION_FAILED — por exemplo INVALID_TAG.
especificação
a referência abaixo é gerada a partir da especificação, então esta página não consegue divergir dela. aponte seu gerador de cliente para /openapi.json — ou /openapi.yaml se preferir ler.
o que não está aqui
a API cobre o que dá para automatizar. de fora ficam o login (é código por e-mail, não dá para roteirizar), a administração da conta — trocar e-mail, encerrar sessões, apagar a conta, criar tokens —, o envio de fotos e os contadores internos do site.
os contadores ficam de fora porque um estranho escrevendo nas nossas métricas não é uma funcionalidade. POST /reports é o contrário — ali o estranho escrevendo é a funcionalidade — então está documentado, mesmo sendo público e sem autenticação.
a maior parte disso não é escolha de documentação: com um token, esses endpoints respondem 403 de propósito. é o que faz a revogação de um token valer alguma coisa.
referência
base: https://api.arvore.link · versão 1.0.0
links
/linkstokenlistar seus links curtos
200 Links401 Unauthorized
resposta 200 · Link
{
"links": [
{
"tags": [
"…"
],
"expires_at": 1785400000000,
"expiration_url": "https://example.com/campaign-over",
"targeting": {
"geo": {
"BR": "https://example.com.br",
"PT": "https://example.pt"
},
"ios": "https://apps.apple.com/app/id1234567890",
"android": "https://play.google.com/store/apps/details?id=com.example"
},
"has_password": false,
"og_title": "Promotion ends Sunday",
"og_description": "Free shipping on everything",
"og_image": "https://assets.arvore.link/avatars/ws000001/og-a1b2c3d4-x9.webp",
"id": "a1b2c3d4",
"slug": "a1b2",
"url": "https://example.com",
"short_url": "https://arvr.ink/a1b2",
"redirect_domain": "arvr.ink",
"created_at": 1739111400000,
"updated_at": 1739111400000,
"deleted_at": null
}
]
}- tags
- — string[]. For grouping links so they can be found later. Lowercase, digits and hyphens, at most 10 per link. Always present on read, `[]` for an untagged link.
- expires_at
- — integer, pode ser null. When the link stops working, in milliseconds since the epoch. Always present on read, `null` when the link does not expire. After this moment the link redirects to `expiration_url` if one is set, and answers 404 otherwise.
- expiration_url
- — string, pode ser null. Where an expired link goes instead of answering 404. Always present on read, `null` when unset. Only meaningful alongside `expires_at`.
- targeting
- — object, pode ser null. Per-visitor destinations. Always present on read, `null` when the link has none. Evaluated on every request: the operating system rule wins over the country rule, and a visitor matching neither goes to `url`. An expired link ignores targeting entirely.
- has_password
- — boolean. Whether a password is required to open the link. A boolean and never the hash: the hash is stored only on the record the redirect app reads, so there is nothing here to leak. The password itself is write-only and can never be read back — the same once-only property an API token has.
- og_title
- — string, pode ser null. Custom title for the share card. When any og_ field is set, the redirect answers HTML carrying these tags to social scrapers instead of a 301; everyone else, including search crawlers, still gets the 301.
- og_description
- — string, pode ser null
- og_image
- — string, pode ser null. Image for the share card, 1200x630. Any absolute http(s) URL — it does not have to be hosted here. When unset but a title is present, an image is generated from the title, so a card needs no upload to exist.
- id
- — string. Internal link id, 8 characters
- slug
- — string. Path on the redirect domain
- url
- — string
- short_url
- — string
- redirect_domain
- — string
- created_at
- — integer. Unix timestamp in milliseconds
- updated_at
- — integer. Unix timestamp in milliseconds
- deleted_at
- — integer, pode ser null
/linkstoken opcionalcriar um link curto
- url
- — string, obrigatório. ex: https://example.com
- slug
- — string, opcional. ex: meu-link
- tags
- — array, opcional. ex: campanha-verao,instagram
- expires_at
- — integer, opcional. ex: 1785400000000
- expiration_url
- — string, opcional. ex: https://example.com/campaign-over
- targeting
- — object, opcional
- password
- — string, opcional. ex: verao2026
- og_title
- — string, opcional. ex: Promotion ends Sunday
- og_description
- — string, opcional. ex: Free shipping on everything
- og_image
- — string, opcional. ex: https://example.com/card.png
201 Link created400 Validation error409 LINK_ID_ALREADY_IN_USE429
resposta 201 · Link
{
"tags": [
"…"
],
"expires_at": 1785400000000,
"expiration_url": "https://example.com/campaign-over",
"targeting": {
"geo": {
"BR": "https://example.com.br",
"PT": "https://example.pt"
},
"ios": "https://apps.apple.com/app/id1234567890",
"android": "https://play.google.com/store/apps/details?id=com.example"
},
"has_password": false,
"og_title": "Promotion ends Sunday",
"og_description": "Free shipping on everything",
"og_image": "https://assets.arvore.link/avatars/ws000001/og-a1b2c3d4-x9.webp",
"id": "a1b2c3d4",
"slug": "a1b2",
"url": "https://example.com",
"short_url": "https://arvr.ink/a1b2",
"redirect_domain": "arvr.ink",
"created_at": 1739111400000,
"updated_at": 1739111400000,
"deleted_at": null
}- tags
- — string[]. For grouping links so they can be found later. Lowercase, digits and hyphens, at most 10 per link. Always present on read, `[]` for an untagged link.
- expires_at
- — integer, pode ser null. When the link stops working, in milliseconds since the epoch. Always present on read, `null` when the link does not expire. After this moment the link redirects to `expiration_url` if one is set, and answers 404 otherwise.
- expiration_url
- — string, pode ser null. Where an expired link goes instead of answering 404. Always present on read, `null` when unset. Only meaningful alongside `expires_at`.
- targeting
- — object, pode ser null. Per-visitor destinations. Always present on read, `null` when the link has none. Evaluated on every request: the operating system rule wins over the country rule, and a visitor matching neither goes to `url`. An expired link ignores targeting entirely.
- has_password
- — boolean. Whether a password is required to open the link. A boolean and never the hash: the hash is stored only on the record the redirect app reads, so there is nothing here to leak. The password itself is write-only and can never be read back — the same once-only property an API token has.
- og_title
- — string, pode ser null. Custom title for the share card. When any og_ field is set, the redirect answers HTML carrying these tags to social scrapers instead of a 301; everyone else, including search crawlers, still gets the 301.
- og_description
- — string, pode ser null
- og_image
- — string, pode ser null. Image for the share card, 1200x630. Any absolute http(s) URL — it does not have to be hosted here. When unset but a title is present, an image is generated from the title, so a card needs no upload to exist.
- id
- — string. Internal link id, 8 characters
- slug
- — string. Path on the redirect domain
- url
- — string
- short_url
- — string
- redirect_domain
- — string
- created_at
- — integer. Unix timestamp in milliseconds
- updated_at
- — integer. Unix timestamp in milliseconds
- deleted_at
- — integer, pode ser null
/links/{id}tokeneditar destino, id, tags, expiração, segmentação, senha ou prévia
- id
- — path, obrigatório
- url
- — string, opcional
- slug
- — string, opcional
- tags
- — array, opcional. ex: campanha-verao,instagram
- expires_at
- — integer, opcional. ex: 1785400000000
- expiration_url
- — string, opcional. ex: https://example.com/campaign-over
- targeting
- — object, opcional
- password
- — string, opcional. ex: verao2026
- og_title
- — string, opcional. ex: Promotion ends Sunday
- og_description
- — string, opcional. ex: Free shipping on everything
- og_image
- — string, opcional. ex: https://example.com/card.png
200 Link updated400 Validation error401 Unauthorized404 Link not found409 LINK_ID_ALREADY_IN_USE or LINKTREE_LINK_NOT_EDITABLE
resposta 200 · Link
{
"tags": [
"…"
],
"expires_at": 1785400000000,
"expiration_url": "https://example.com/campaign-over",
"targeting": {
"geo": {
"BR": "https://example.com.br",
"PT": "https://example.pt"
},
"ios": "https://apps.apple.com/app/id1234567890",
"android": "https://play.google.com/store/apps/details?id=com.example"
},
"has_password": false,
"og_title": "Promotion ends Sunday",
"og_description": "Free shipping on everything",
"og_image": "https://assets.arvore.link/avatars/ws000001/og-a1b2c3d4-x9.webp",
"id": "a1b2c3d4",
"slug": "a1b2",
"url": "https://example.com",
"short_url": "https://arvr.ink/a1b2",
"redirect_domain": "arvr.ink",
"created_at": 1739111400000,
"updated_at": 1739111400000,
"deleted_at": null
}- tags
- — string[]. For grouping links so they can be found later. Lowercase, digits and hyphens, at most 10 per link. Always present on read, `[]` for an untagged link.
- expires_at
- — integer, pode ser null. When the link stops working, in milliseconds since the epoch. Always present on read, `null` when the link does not expire. After this moment the link redirects to `expiration_url` if one is set, and answers 404 otherwise.
- expiration_url
- — string, pode ser null. Where an expired link goes instead of answering 404. Always present on read, `null` when unset. Only meaningful alongside `expires_at`.
- targeting
- — object, pode ser null. Per-visitor destinations. Always present on read, `null` when the link has none. Evaluated on every request: the operating system rule wins over the country rule, and a visitor matching neither goes to `url`. An expired link ignores targeting entirely.
- has_password
- — boolean. Whether a password is required to open the link. A boolean and never the hash: the hash is stored only on the record the redirect app reads, so there is nothing here to leak. The password itself is write-only and can never be read back — the same once-only property an API token has.
- og_title
- — string, pode ser null. Custom title for the share card. When any og_ field is set, the redirect answers HTML carrying these tags to social scrapers instead of a 301; everyone else, including search crawlers, still gets the 301.
- og_description
- — string, pode ser null
- og_image
- — string, pode ser null. Image for the share card, 1200x630. Any absolute http(s) URL — it does not have to be hosted here. When unset but a title is present, an image is generated from the title, so a card needs no upload to exist.
- id
- — string. Internal link id, 8 characters
- slug
- — string. Path on the redirect domain
- url
- — string
- short_url
- — string
- redirect_domain
- — string
- created_at
- — integer. Unix timestamp in milliseconds
- updated_at
- — integer. Unix timestamp in milliseconds
- deleted_at
- — integer, pode ser null
/links/{id}tokenapagar um link curto
- id
- — path, obrigatório
204 Deleted, or already was404 NOT_FOUND409 LINKTREE_LINK_NOT_EDITABLE
resposta 204 sem corpo.
/links/{id}/analyticstokenver os cliques de um link
- id
- — path, obrigatório
- from
- — query. Start of time range (Unix timestamp in milliseconds, inclusive)
- to
- — query. End of time range (Unix timestamp in milliseconds, inclusive)
200 Analytics data401 Unauthorized404 Link not found
resposta 200 · ClickEvent
{
"count": 42,
"clicks": [
{
"ts": "1771849585571#k9fx2n1a",
"timestamp": 1771849585571,
"country": "BR",
"region": "SP",
"region_name": "São Paulo",
"timezone": "America/Sao_Paulo",
"lat": -23.673,
"lng": -46.5302,
"device": "desktop",
"platform": "macOS",
"browser": "Chrome 145",
"referer": "https://twitter.com"
}
]
}- ts
- — string. Sort key in the format "{timestamp_ms}#{random}"
- timestamp
- — integer. Unix timestamp in milliseconds
- country
- — string, pode ser null
- region
- — string, pode ser null
- region_name
- — string, pode ser null
- timezone
- — string, pode ser null
- lat
- — number, pode ser null
- lng
- — number, pode ser null
- device
- — string
- platform
- — string, pode ser null
- browser
- — string, pode ser null
- referer
- — string, pode ser null
árvores
/linktreestokenlistar suas árvores
200 Linktrees401 Unauthorized
resposta 200 · Linktree
{
"linktrees": [
{
"id": "k9fx2n1a",
"slug": "meu-perfil",
"title": "minha página",
"bio": "links que importam",
"avatar_url": "https://example.com/foto.jpg",
"published": false,
"created_at": 1739111400000,
"updated_at": 1739111400000
}
]
}- id
- — string
- slug
- — string. Path on the redirect domain, 1-50 chars of [0-9a-z-]
- title
- — string
- bio
- — string, pode ser null
- avatar_url
- — string, pode ser null
- published
- — boolean. Unpublished árvores 404 on the public page
- created_at
- — integer
- updated_at
- — integer
/linktreestokencriar uma árvore
- slug
- — string, obrigatório. ex: meu-perfil
- title
- — string, obrigatório
- bio
- — string, opcional
- avatar_url
- — string, opcional
201 Linktree created400 Validation error409 SLUG_ALREADY_IN_USE
resposta 201 · Linktree
{
"id": "k9fx2n1a",
"slug": "meu-perfil",
"title": "minha página",
"bio": "links que importam",
"avatar_url": "https://example.com/foto.jpg",
"published": false,
"created_at": 1739111400000,
"updated_at": 1739111400000
}- id
- — string
- slug
- — string. Path on the redirect domain, 1-50 chars of [0-9a-z-]
- title
- — string
- bio
- — string, pode ser null
- avatar_url
- — string, pode ser null
- published
- — boolean. Unpublished árvores 404 on the public page
- created_at
- — integer
- updated_at
- — integer
/linktrees/{id}tokenver uma árvore com seus itens
- id
- — path, obrigatório
200 Linktree with items401 Unauthorized404 Not found
resposta 200 · Linktree
{
"id": "k9fx2n1a",
"slug": "meu-perfil",
"title": "minha página",
"bio": "links que importam",
"avatar_url": "https://example.com/foto.jpg",
"published": false,
"created_at": 1739111400000,
"updated_at": 1739111400000,
"items": [
{
"id": "p3qr7s2t",
"title": "instagram",
"url": "https://instagram.com/perfil",
"short_url": "https://arvr.ink/x7y8",
"position": 0,
"active": true,
"created_at": 1739111400000,
"updated_at": 1739111400000
}
]
}- id
- — string
- slug
- — string. Path on the redirect domain, 1-50 chars of [0-9a-z-]
- title
- — string
- bio
- — string, pode ser null
- avatar_url
- — string, pode ser null
- published
- — boolean. Unpublished árvores 404 on the public page
- created_at
- — integer
- updated_at
- — integer
- items
- — LinktreeItem[]
/linktrees/{id}tokeneditar o perfil, o slug ou publicar uma árvore
- id
- — path, obrigatório
- slug
- — string, opcional
- title
- — string, opcional
- bio
- — string, opcional
- avatar_url
- — string, opcional
- published
- — boolean, opcional
200 Linktree updated400 Validation error401 Unauthorized404 Not found409 SLUG_ALREADY_IN_USE
resposta 200 · Linktree
{
"id": "k9fx2n1a",
"slug": "meu-perfil",
"title": "minha página",
"bio": "links que importam",
"avatar_url": "https://example.com/foto.jpg",
"published": false,
"created_at": 1739111400000,
"updated_at": 1739111400000
}- id
- — string
- slug
- — string. Path on the redirect domain, 1-50 chars of [0-9a-z-]
- title
- — string
- bio
- — string, pode ser null
- avatar_url
- — string, pode ser null
- published
- — boolean. Unpublished árvores 404 on the public page
- created_at
- — integer
- updated_at
- — integer
/linktrees/{id}tokenapagar uma árvore
- id
- — path, obrigatório
204 Deleted401 Unauthorized404 Not found
resposta 204 sem corpo.
/linktrees/{id}/analyticstokenver as visitas e os cliques de uma árvore
- id
- — path, obrigatório
- from
- — query. Start of time range (Unix timestamp in milliseconds, inclusive)
- to
- — query. End of time range (Unix timestamp in milliseconds, inclusive)
200 Analytics data401 Unauthorized404 Not found
resposta 200 · LinktreeAnalytics
{
"id": "k9fx2n1a",
"slug": "meu-perfil",
"title": "minha página",
"published": true,
"views": 128,
"clicks": 41,
"items": [
{
"id": "p3qr7s2t",
"title": "instagram",
"short_url": "https://arvr.ink/x7y8",
"active": true,
"count": 22
}
]
}- id
- — string
- slug
- — string
- title
- — string
- published
- — boolean
- views
- — integer. Visits to the public page in the range
- clicks
- — integer. Sum of item clicks in the range
- items
- — object[]
/linktrees/{id}/itemstokenadicionar um item na árvore
- id
- — path, obrigatório
- title
- — string, obrigatório. ex: instagram
- url
- — string, obrigatório. ex: https://instagram.com/perfil
- position
- — integer, opcional
201 Item created400 Validation error401 Unauthorized404 Linktree not found
resposta 201 · LinktreeItem
{
"id": "p3qr7s2t",
"title": "instagram",
"url": "https://instagram.com/perfil",
"short_url": "https://arvr.ink/x7y8",
"position": 0,
"active": true,
"created_at": 1739111400000,
"updated_at": 1739111400000
}- id
- — string
- title
- — string
- url
- — string. Final destination
- short_url
- — string. Short link the public page points at, so clicks are counted
- position
- — integer. Ascending order on the public page
- active
- — boolean. Inactive items are hidden from the public page
- created_at
- — integer
- updated_at
- — integer
/linktrees/{id}/items/{itemId}tokeneditar um item da árvore
- id
- — path, obrigatório
- itemId
- — path, obrigatório
- title
- — string, opcional
- url
- — string, opcional
- position
- — integer, opcional
- active
- — boolean, opcional
200 Item updated400 Validation error401 Unauthorized404 Linktree or item not found
resposta 200 · LinktreeItem
{
"id": "p3qr7s2t",
"title": "instagram",
"url": "https://instagram.com/perfil",
"short_url": "https://arvr.ink/x7y8",
"position": 0,
"active": true,
"created_at": 1739111400000,
"updated_at": 1739111400000
}- id
- — string
- title
- — string
- url
- — string. Final destination
- short_url
- — string. Short link the public page points at, so clicks are counted
- position
- — integer. Ascending order on the public page
- active
- — boolean. Inactive items are hidden from the public page
- created_at
- — integer
- updated_at
- — integer
/linktrees/{id}/items/{itemId}tokenapagar um item da árvore
- id
- — path, obrigatório
- itemId
- — path, obrigatório
204 Deleted401 Unauthorized404 Linktree or item not found
resposta 204 sem corpo.
métricas
/analyticstokenver os cliques de todos os seus links
- link_id
- — query
- from
- — query. Start of time range (Unix timestamp in milliseconds, inclusive)
- to
- — query. End of time range (Unix timestamp in milliseconds, inclusive)
200 Analytics data401 Unauthorized404 Link not found
resposta 200 · ClickEvent
{
"count": 128,
"clicks": [
{
"ts": "1771849585571#k9fx2n1a",
"timestamp": 1771849585571,
"country": "BR",
"region": "SP",
"region_name": "São Paulo",
"timezone": "America/Sao_Paulo",
"lat": -23.673,
"lng": -46.5302,
"device": "desktop",
"platform": "macOS",
"browser": "Chrome 145",
"referer": "https://twitter.com",
"link_id": "a1b2c3d4"
}
]
}- ts
- — string. Sort key in the format "{timestamp_ms}#{random}"
- timestamp
- — integer. Unix timestamp in milliseconds
- country
- — string, pode ser null
- region
- — string, pode ser null
- region_name
- — string, pode ser null
- timezone
- — string, pode ser null
- lat
- — number, pode ser null
- lng
- — number, pode ser null
- device
- — string
- platform
- — string, pode ser null
- browser
- — string, pode ser null
- referer
- — string, pode ser null
- link_id
- — string
conta
/accounttokendescobrir de quem é o token e qual workspace ele acessa
200 Account401 Unauthorized
resposta 200 · Account
{
"user": {
"id": "a1b2c3d4",
"email": "voce@exemplo.com",
"name": "Rafael",
"avatar_url": "https://assets.arvore.link/avatars/w1/user-a1b2c3d4-k9fx2n1a.webp",
"created_at": 1739111400000
},
"workspace": {
"id": "w1x2y3z4",
"name": "Pessoal"
}
}- user
- — object
- workspace
- — object
denúncias
/reportspúblicodenunciar um link curto
- url
- — string, obrigatório. ex: https://arvr.ink/a1b2
- reason
- — string, obrigatório. ex: phishing
- detail
- — string, opcional. ex: Recebi por SMS dizendo que era o banco
- — string, opcional. ex: quem@reportou.com
200 Report received, or silently discarded for an unknown slug400 NOT_A_SHORT_LINK or a validation error429
resposta 200
{
"ok": true
}- ok
- — boolean