Axuz Developers

Área pública e assignees externos

Como publicar boards, arquivos, formulários e fluxogramas por link público (capability URL), o que o visitante anônimo pode fazer e como atribuir tarefas a pessoas de fora do workspace.

Algumas rotas da API não exigem login: quem tem o link, acessa. Esta página explica o modelo (capability URL), as cinco superfícies públicas que existem hoje, como criar e revogar links, o que o visitante anônimo não pode fazer e como atribuir uma tarefa a alguém que não é membro do workspace.

Um link público carrega a credencial no próprio caminho: /public/shares/<token>. Não há cookie nem Authorization; o token é a permissão. Por isso:

  • o token é gerado por CSPRNG com 32 bytes em base64url (43 caracteres), impossível de adivinhar;
  • ele é mostrado uma única vez, na criação (no board público o servidor guarda apenas o SHA-256);
  • quem recebe o link pode repassá-lo. Trate-o como uma senha: não o coloque em logs, issues ou analytics;
  • revogar o link tem efeito imediato.

Superfícies públicas

SuperfícieHostRotas sem loginQuem cria o link
Board (kanban) somente leituraapi-workspaceGET /public/shares/{token}owner/admin do team
Arquivo do Drivefiles-apiGET /share/{token}, /info, POST /verify, /preview, /downloaduploader do arquivo ou owner/admin
Formulário publicadoapi-formsGET /public/forms/{slug}, /render, POST /submit, POST /pre-submitquem publica o formulário
Fluxogramaapi-flowGET /public/shared/{token} (e subrotas)membro com acesso ao fluxograma
Sala de reunião públicameet-apiPOST /rooms/{id}/anonymous-token, POST /rooms/by-slug/{slug}/anonymous-tokensala com visibility=public

Os hosts são https://<serviço>.axuz.net (staging) e https://<serviço>.axuz.club (produção). Veja Conceitos da API.

Board público (somente leitura)

Criar, listar e revogar

Estas rotas exigem sessão e papel owner ou admin do team. Membro comum que enxerga o board recebe 403; quem não enxerga o board (outro tenant, canal fechado) recebe 404.

POST/teams/{teamId}/boards/{id}/public-shares GET/teams/{teamId}/boards/{id}/public-shares DELETE/teams/{teamId}/boards/{id}/public-shares/{shareId}

curl

curl -sS -X POST "https://api-workspace.axuz.net/teams/$TEAM_ID/boards/$BOARD_ID/public-shares" \
  -H "Authorization: Bearer $AXUZ_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"show_assignees": true, "show_due_dates": true, "expires_at": "2026-12-31T23:59:59Z"}'

Corpo (todos opcionais, campo desconhecido é 400):

CampoPadrãoEfeito
show_assigneesfalsemostra os responsáveis (só o nome de exibição)
show_due_datesfalsemostra prazos
show_descriptionsfalsemostra descrições do board e das tarefas
expires_atsem expiraçãodata futura, no máximo 365 dias

A resposta 201 traz os metadados e o campo token, só nesta resposta. O GET de listagem nunca devolve o token: se perdeu, revogue e crie outro. Limite de 20 links ativos por board (422 too many active shares). Revogar é idempotente (204 mesmo se já revogado).

Ler como visitante anônimo

GET/public/shares/{token}
curl -sS "https://api-workspace.axuz.net/public/shares/$SHARE_TOKEN"

A resposta é um formato dedicado e mínimo: name, description, columns[] com tasks[] (title, description, priority, due_at, is_all_day, assignees[]). Nunca saem e-mails, ids de usuário, comentários, anexos, campos customizados, labels, checklists nem ids de task/board/team.

Segurança desta rota:

  • token inexistente, malformado, expirado, revogado ou de board apagado respondem sempre o mesmo 404 {"error":"not_found"}, para não revelar qual caso ocorreu (anti-enumeração);
  • rate limit por IP, padrão 60 requisições/min, 429 com Retry-After;
  • toda resposta leva Cache-Control: no-store, X-Robots-Tag: noindex, nofollow, Referrer-Policy: no-referrer;
  • sem CORS aberto: o front consome pelo mesmo origin (BFF). Chamar de JavaScript em outro site não é suportado.

Arquivo do Drive (senha, expiração, download)

O criador do link (sessão necessária) define opções. Esta é a única superfície com senha.

POST/teams/{teamId}/files/{fileId}/share-links
curl -sS -X POST "https://files-api.axuz.net/teams/$TEAM_ID/files/$FILE_ID/share-links" \
  -H "Authorization: Bearer $AXUZ_TOKEN" -H "Content-Type: application/json" \
  -d '{"password": "'"$LINK_PASSWORD"'", "allow_download": true, "expires_in_hours": 48}'

expires_in_hours vai de 1 a 8760 (365 dias); 0 ou ausente = não expira. allow_download padrão false (somente visualização). A resposta traz token e public_url; o token só é visível para quem criou o link. Revogar: DELETE /teams/{teamId}/files/{fileId}/share-links/{shareLinkId}.

O visitante usa:

  1. GET /share/{token}/info: nome, tamanho, tipo, has_password, allow_download, expires_at.
  2. Se has_password, POST /share/{token}/verify com {"password": "..."} devolve session_token (válido por 1 hora). Senha errada é 401 e não incrementa o contador de acessos.
  3. GET /share/{token}/preview?session=<jwt> (inline) ou GET /share/{token}/download?session=<jwt> (anexo; exige allow_download, senão 403). A sessão também pode ir no header X-Share-Session.
SESSION=$(curl -sS -X POST "https://files-api.axuz.net/share/$FILE_TOKEN/verify" \
  -H "Content-Type: application/json" -d '{"password": "'"$LINK_PASSWORD"'"}' | jq -r .session_token)
curl -sS -L -o arquivo.bin "https://files-api.axuz.net/share/$FILE_TOKEN/download?session=$SESSION"

Aqui, diferente do board, link revogado ou expirado responde 410 Gone e inexistente 404: o serviço de arquivos distingue os casos. Não existe rate limit específico documentado para /share/* além da proteção geral do serviço; não documentado ainda.

Formulário publicado

Formulários publicados são acessados pelo slug, não por token. Não exigem login nem origem específica (podem ser embutidos em qualquer site).

curl -sS "https://api-forms.axuz.net/public/forms/$FORM_SLUG"
curl -sS -X POST "https://api-forms.axuz.net/public/forms/$FORM_SLUG/submit" \
  -H "Content-Type: application/json" \
  -d '{"nome": "Maria", "email": "maria@example.test"}'

Detalhes verificados no código: rate limit de 10 envios por minuto por IP e formulário (429); campo honeypot axuz_hp quando ligado no formulário; tokens opcionais recaptcha_token/turnstile_token verificados em segundo plano; validação de campos devolve 422 com fields; sucesso devolve 201 imediatamente (spam é marcado depois e o visitante não vê a diferença). O corpo pode ser JSON ou application/x-www-form-urlencoded. pre-submit salva rascunho parcial. Formulário não publicado ou inexistente: 404.

Fluxograma compartilhado

O dono cria links em POST /teams/{teamId}/flowcharts/{id}/shares com mode (public, time, email), access (view, interact), expires_at, target_email (modo email) e max_views. O visitante lê GET /public/shared/{token}, que devolve title, document, readonly e share. No modo email o visitante precisa estar logado como o e-mail alvo (403 com requires_login). Há rate limit de 240 requisições/min por token e o link se auto-revoga ao atingir max_views. Links access=interact permitem enviar edições pelas subrotas /ops, /document e /draft; veja a referência para o contrato completo.

Sala de reunião pública (visitante)

Para salas com visibility=public, qualquer pessoa obtém um token de entrada informando um nome:

curl -sS -X POST "https://meet-api.axuz.net/rooms/by-slug/$ROOM_SLUG/anonymous-token" \
  -H "Content-Type: application/json" -d '{"guest_name": "Visitante"}'

Resposta: join_url, jwt, expires_at e guest_id. guest_name é obrigatório (400); o visitante nunca é moderador. Sala não pública responde 404, igual a sala inexistente.

O que o visitante anônimo pode e não pode fazer

PodeNão pode
Ler o board publicado no recorte escolhido pelo donoEscrever, comentar, mover tarefas
Ver/baixar o arquivo (se allow_download)Listar outros arquivos, ver o dono ou o team
Enviar uma resposta de formulárioLer respostas anteriores
Entrar na sala pública com nome de visitanteModerar ou entrar em sala privada
Ver o fluxograma; editar só se access=interactListar ou ver outros fluxogramas

Assignees externos

Um assignee externo é uma pessoa de fora do workspace atribuída a uma tarefa, para fins de apresentação (por exemplo, mostrar ao cliente quem do lado dele é responsável). No código atual ele é apenas um rótulo: name (1 a 80 caracteres), organization opcional e show_on_public.

POST/teams/{teamId}/tasks/{id}/external-assignees GET/teams/{teamId}/tasks/{id}/external-assignees DELETE/teams/{teamId}/tasks/{id}/external-assignees/{assigneeId}
curl -sS -X POST "https://api-workspace.axuz.net/teams/$TEAM_ID/tasks/$TASK_ID/external-assignees" \
  -H "Authorization: Bearer $AXUZ_TOKEN" -H "Content-Type: application/json" \
  -d '{"name": "Ana Souza", "organization": "Cliente Exemplo", "show_on_public": true}'

Qualquer membro do team com acesso ao módulo de tarefas do canal pode adicionar ou remover. Limite de 25 externos ativos por tarefa (422). A remoção é idempotente (204) e o nome some imediatamente do board público. Eventos emitidos: task.external_assignee.added e task.external_assignee.removed. No board público o externo aparece em assignees[] com external: true e a organização, se show_assignees estiver ligado no link e show_on_public for true.

Erros comuns e o que não fazer

  • Formato de erro: o serviço de workspace responde {"error": "<frase>"}, não RFC 9457.
  • 403 ao criar link público: você é membro, mas não owner/admin do team.
  • 422 too many active shares: revogue links antigos (máximo 20 por board).
  • 400 invalid expires_at: a data deve ser futura e dentro de 365 dias.
  • Não chame /public/shares/{token} de JavaScript no browser de outro site: não há CORS.
  • Não registre URLs públicas em logs de aplicação nem as envie por canais que gerem preview indexável.
  • Não use e-mail de pessoas reais em testes; use @example.test.

Atualizado em