REST API
Envie arquivos, crie coleções e gerencie compartilhamentos via HTTP. Todas as respostas são em JSON; não é necessária uma chave de API para uploads anônimos.
Introdução
A API do storage.to alimenta nosso CLI, app de desktop, enviador web e qualquer cliente de terceiros que você queira criar.
O fluxo de envio tem três etapas:
- Iniciar — diga que você quer enviar um arquivo. Nós retornamos uma ou mais URLs presignadas apontando para o Cloudflare R2.
- Enviar para o R2 — :coloque seus bytes diretamente na(s) URL(s) pré-assinada(s). Os bytes não passam pelos nossos servidores.
- Confirmar — diga que o envio foi concluído. Criamos um registro
Filee entregamos uma URL compartilhável.
URL base
https://storage.to/api
Todos os endpoints abaixo são relativos a esta base. Exemplo: POST /upload/init significa POST https://storage.to/api/upload/init.
Autenticação
A maioria dos endpoints não exige autenticação. Uploads anônimos são um recurso essencial.
A autenticação é opcional e desbloqueia:
- Uploads vinculados à sua conta (visível em /dashboard)
- Recursos premium (arquivos permanentes, mais armazenamento)
- Mutations baseadas em propriedade (excluir, definir senha, alterar validade) sem precisar do match do visitor-token
Usamos tokens bearer Laravel Sanctum. Emita um token via o handoff do OAuth no desktop ou pelo login web e, em seguida, envie-o como:
Authorization: Bearer <token>
Token de visitante
Clientes anônimos precisam de uma forma de provar a propriedade dos próprios uploads sem ter uma conta. Usamos um visitor token — uma string aleatória que o cliente gera uma vez e reutiliza. Envie com toda requisição:
X-Visitor-Token: <random-string>
No web, o token é armazenado automaticamente no cookie visitor_token. O CLI o armazena em ~/.config/storageto/token (veja Documentação da CLI).
Para endpoints de mutação (delete, definir senha, alterar validade), a propriedade é confirmada se ou o token do visitante corresponder a ou a requisição vier do mesmo IP que criou o arquivo. Ambos podem ser perdidos (cookies apagados, mudanças de rede). O token do proprietário é a prova preferida daqui pra frente.
Token do proprietário
Todo endpoint que cria recursos (/upload/init multipart, /upload/confirm, /upload/reserve, /collection) retorna um owner_token na resposta. O token é uma prova de propriedade assinada, vinculada a esse recurso específico, independente do seu IP ou do token do visitante.
Guarde o token junto com o ID do recurso e envie-o em qualquer mutação como:
Authorization: Owner <token>
Ou, se você já estiver usando Authorization: Bearer para uma sessão autenticada, envie como:
X-Owner-Token: <token>
O servidor aceita o token do proprietário como uma prova válida de propriedade junto com o fallback legado visitor token + IP — clientes que têm o token continuam funcionando após trocar de rede ou limpar cookies, e clientes que não têm continuam funcionando exatamente como antes.
Os tokens duram enquanto o recurso existir, são seguros para persistir e não expiram de forma independente. Um token perdido significa perder o controle desse recurso (arquivo/coleção/upload) — trate-os como senhas locais.
Erros
Os erros seguem um formato consistente:
{
"success": false,
"error": "Human-readable message"
}
Códigos de status HTTP comuns:
| Código | Significado |
|---|---|
200 | OK. |
201 | Criado. |
400 | Requisição inválida (por exemplo, limite de tamanho da coleção excedido). |
401 | Senha necessária ou incorreta. |
403 | Não autorizado (não é o proprietário do recurso). |
404 | Recurso não encontrado ou expirado. |
422 | Falha na validação ou restrição de plano/quota. |
429 | Limite de taxa atingido ou cota de upload excedida. |
500 | Erro no servidor. Verifique status. |
Limites de taxa
Todos os limites de taxa são por IP. Uma resposta 429 inclui os cabeçalhos padrão Retry-After, X-RateLimit-Limit e X-RateLimit-Remaining.
| Escopo | Limite |
|---|---|
| Upload init / confirm / abort | 60 / minuto |
| Conclusão multipart | 500 / minuto |
| URLs das partes multipart | 120 / minuto |
| Batch init / confirm | 500 / minuto |
| Consultas de status (arquivo e coleção) | 120 / minuto |
| Configurações (senha, validade, max-downloads) | 30 / minuto |
| Verificação de senha | 10 / minuto |
| Criação de coleção | 30 / minuto |
| Gerenciar (ready, delete) | 60 / minuto |
| Upload de miniatura | 120 / minuto |
| Upload pelo ShareX | 20 / dia |
| Analytics do app / erros | 120 e 60 / minuto |
Cota de upload: clientes anônimos têm dois limites em paralelo — 100 GB / 24 h por visitor token e 500 GB / 24 h por IP (o limite de IP captura tráfego sem token e redes compartilhadas). Quando qualquer um for excedido, você recebe um 429 com detalhes. Isso é apenas uma upload cota — downloads são ilimitados e sem limitação (servidos diretamente das URLs assinadas do R2).
Upload
O fluxo de upload em três etapas para qualquer arquivo, incluindo arquivos acima de 5 GB (multipart automático). Se você só precisa de um upload rápido no estilo de captura de tela, veja ShareX.
/upload/init
60/min
Inicie um upload. Para arquivos >50 MB, a resposta é um upload multipart (campo type: "multipart"); caso contrário, um único PUT presignado.
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
filename | string · required | Nome original do arquivo. Máx. 255 caracteres. |
content_type | string · required | Tipo MIME. |
size | integer · required | Tamanho do arquivo em bytes. Mín. 1. |
/upload/parts
Owner only
120/min
Solicita URLs adicionais das partes para um upload multipart em andamento. Usado quando /init retornou menos URLs do que você tem partes (ou elas expiraram).
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
upload_id | string · required | O upload_id de /init. |
part_numbers | array<int> · required | Números das partes para obter URLs. |
/upload/complete-multipart
Owner only
500/min
Finaliza um upload multipart no R2 assim que todas as partes forem enviadas.
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
upload_id | string · required | O upload_id de /init. |
parts | array · required | Cada entrada: { partNumber, etag } da resposta do R2. |
/upload/abort
Owner only
60/min
Cancele um upload multipart e limpe qualquer dado parcial no R2.
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
upload_id | string · required | O upload a ser interrompido. |
/upload/confirm
60/min
Confirme que o upload foi concluído. É quando criamos o registro File e retornamos a URL compartilhável.
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
filename | string · required | Nome original do arquivo. |
size | integer · required | Tamanho do arquivo em bytes. |
content_type | string · required | Tipo MIME. |
r2_key | string · required | O r2_key de /init. |
collection_id | string · optional | Anexar a uma coleção. |
crc32 | integer · optional | Soma de verificação CRC32 para verificação de integridade. |
file_id | string(9) · optional | Concluir um ID de arquivo reservado previamente. |
/file/reserve
60/min
Reserve um ID de arquivo e uma URL compartilhável antes os bytes ficarem prontos. Útil quando você precisa entregar um link primeiro e concluir o upload depois. A propriedade fica vinculada ao seu token de visitante + IP. Finalize o upload mais tarde com /upload/init + /upload/confirm, passando file_id para confirmar.
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
filename | string · optional | Nome de arquivo de exemplo. Padrão: "Pending". |
content_type | string · optional | Tipo MIME de exemplo. |
/upload/init-batch
500/min
Equivalente em lote de /upload/init, otimizado para o uploader web. Inicia até 250 arquivos em uma única ida e volta.
Usado internamente pelo uploader web. A maioria dos clientes deve preferir o /upload/init de arquivo único.
/upload/confirm-batch
500/min
Equivalente em lote de /upload/confirm. Confirma muitos arquivos em uma única ida e volta.
Coleções
Uma coleção agrupa vários arquivos sob uma única URL de compartilhamento (/c/{id}). Até 10.000 arquivos e 25 GB no total.
/collection
30/min
Crie uma nova coleção. Anexe arquivos depois passando collection_id em /upload/confirm.
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
expected_file_count | integer · optional | Dica para marcar automaticamente a coleção como pronta assim que todos os arquivos esperados forem confirmados. |
/collection/{id}/status
120/min
Verifica o estado de uma coleção. Também marca automaticamente a coleção como pronta se todos os arquivos esperados tiverem sido confirmados.
/collection/{id}/ready
Owner only
60/min
Marque a coleção como pronta para download. Normalmente não é necessário — as coleções ficam prontas automaticamente quando expected_file_count é atingido.
/collection/{id}
Owner only
60/min
Exclua uma coleção e todos os seus arquivos.
/collection/{id}/password
Owner only
30/min
Defina uma senha na coleção. Requer 4–100 caracteres.
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
password | string · required | 4–100 caracteres. |
/collection/{id}/password
Owner only
30/min
Remover a senha de uma coleção.
/collection/{id}/verify-password
10/min
Verifique uma senha. Retorna 200 em caso de sucesso, 401 em caso de senha incorreta.
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
password | string · required |
/collection/{id}/expiry
Owner only
30/min
Altere a expiração de uma coleção.
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
days | integer · optional | De 1 a 7 dias a partir de agora. Omitir ou null para permanente (apenas premium). |
/collection/{id}/max-downloads
Owner only
30/min
Defina um limite de downloads (burn-after-N-downloads). A coleção é excluída automaticamente quando atingir o limite.
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
max_downloads | integer · optional | 1–1000. Deve exceder a contagem atual de downloads. null para remover o limite. |
Arquivos
Todas as configurações no nível do arquivo (senha, expiração, max-downloads) espelham os endpoints da coleção. Apenas o proprietário.
/file/{id}/status
120/min
Verifique se um arquivo ainda está aguardando o upload.
/file/{id}
Owner only
60/min
Exclua um arquivo imediatamente.
/file/{id}/thumbnail
Owner only
120/min
Envie uma imagem de miniatura para um arquivo de vídeo ou imagem (usada na página de download). Máx. 2 MB.
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
thumbnail | image · required | Upload multipart. Máx. 2 MB. |
/file/{id}/password
Owner only
30/min
Defina uma senha em um arquivo. Requer 4–100 caracteres.
/file/{id}/password
Owner only
30/min
Remova a senha de um arquivo.
/file/{id}/verify-password
10/min
Verifique a senha de um arquivo.
/file/{id}/expiry
Owner only
30/min
Altere a expiração de um arquivo.
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
days | integer · optional | De 1 a 7 dias a partir de agora. Omitir ou null para permanente (apenas premium). |
/file/{id}/max-downloads
Owner only
30/min
Limite o total de downloads de um arquivo. Apaga automaticamente quando atingir o limite.
Upload pelo ShareX
Endpoint de upload em uma única etapa — envie um arquivo multipart e receba uma URL compartilhável de volta. Sem a dança de init/confirm. Ideal para ferramentas de captura de tela. Guia completo de configuração em /pt/docs/sharex.
Autenticação no desktop
Para clientes autenticados (por exemplo, o app de desktop) que tenham um token Sanctum.
/user
Bearer token
Retorne o usuário autenticado.
/auth/logout
Bearer token
Revogue o token de acesso atual.
Diversos
/health
Verificação de saúde. Faz ping no banco de dados, no armazenamento R2 e no cache Redis. Retorna 200 se tudo estiver verde; 503 caso contrário.
/activity
Stream ao vivo de atividades para o globo da página inicial. Armazenado em cache na borda da Cloudflare.
/bandwidth/status
60/min
Uso atual da cota de upload do solicitante — usado pela CLI e pelo app de desktop para mostrar a capacidade restante. A estrutura da resposta muda para usuários autenticados. Apesar do nome da URL, isso rastreia apenas upload bytes; downloads não são contabilizados.
/app-analytics
120/min
Envie um evento de uso pela CLI ou pelo app de desktop.
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
app | string · required | desktop, cli ou web. |
version | string · optional | Versão do cliente. |
event | string · required | Nome do evento, por exemplo upload_complete. |
context | object · optional | Metadados extras. |
/app-errors
60/min
Envie um relatório de erro pela CLI ou pelo app de desktop. Deduplicado no servidor — no máximo 10 do mesmo erro por hora.
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
app | string · required | desktop, cli ou web. |
type | string · required | Classe/tipo do erro. |
message | string · required | Mensagem do erro. |
stack | string · optional | Rastreamento (stack trace). |
version, os, os_version, arch, context | various · optional | Metadados de diagnóstico. |