Pede a URL de envio direto de uma mídia
POST/api/media/upload-url
- Auth
- Jeton requis
- Qui peut l’appeler:
- owner
- admin
- moderator
- finance
- Clé d’API:
- media:write
- X-CommunityId
X-CommunityIdEnvoyez le X-CommunityId de la communauté où l’opération a lieu.
Substituiu o antigo envio de vídeo pelo servidor (100 MB, URL pública), removido. Confere finalidade, space, permissão, tipo, extensão e tamanho **antes de assinar** e devolve um `PUT` pré-assinado de 10 minutos amarrado à chave, ao `Content-Type` e ao tamanho exatos. O navegador envia direto ao S3 e depois chama `POST /api/media/confirm`. Só arquivo enviado conta nos minutos de vídeo nativo (o presente `video.trialMinutes` e o mensal `video.transcodeMinutesPerMonth`); link de outra plataforma (YouTube, Vimeo, Bunny, Cloudflare, Panda, HLS) nunca conta. **Armazenamento do plano** (`media.storageGb`: Starter 5, Growth 25, Business 100, Scale 250 GB, ou o limite que o SuperAdmin definiu na comunidade): um envio que passaria dele é recusado com 409 `storageLimitReached` (mensagem com o limite e a sugestão de liberar espaço ou mudar de plano). Os arquivos já guardados continuam. Vale também para `upload-urls`, arquivos de Downloads e aulas.
Finalidades (o space precisa ser do módulo certo): - `contentVideo`: vídeo (MP4, WebM, MOV) de um post, até **2 GB**; space `content` ou `feed`; quem o `canCreate` do space permite. Em comunidade com streaming nativo ligado, a confirmação enfileira a conversão para HLS (`processingStatus`: `queued` → `processing` → `ready`/`failed`). - `eventRecording`: gravação (vídeo) de um evento, até 2 GB; space `events`; só a equipe. - `galleryImage`: imagem (JPG, PNG, WEBP, GIF) até 50 MB; space `gallery`; quem o `canCreate` permite. - `classifiedImage`: imagem até 50 MB; space `classifieds`; quem o `canCreate` permite. - `parcelPhoto`: foto de encomenda (JPG, PNG, WEBP) até 50 MB; space `parcels`; só a equipe (owner, admin, moderador, financeiro). Abre só para a equipe e para o destinatário da encomenda; outro membro recebe 403. - `supportPhoto`: foto de chamado do Suporte (JPG, PNG, WEBP) até 50 MB; space `support`; qualquer membro com acesso ao space envia (não depende de `canCreate`). Os metadados (GPS incluído) são removidos. Abre só para o autor do chamado e para a equipe; a foto de uma nota interna, só para a equipe; outro membro recebe 403. - `statusVideo` (Drops): vídeo gravado no navegador (MP4, WebM, MOV) de um post curto, até **350 MB**; space `content` ou `feed`; quem o `canCreate` do space permite. Vai em `videoMediaId` de `POST`/`PUT /api/status`. - `contentCommentVideo` (Drops): vídeo de um comentário de post, até 350 MB; `spaceId` é o space do post; qualquer membro que lê o space (não depende de `canCreate`). Vai em `videoMediaId` de `POST /api/content/{id}/comment` e do `PUT` do comentário. - `statusCommentVideo` (Drops): vídeo de um comentário de post curto, até 350 MB; `spaceId` é o space do post curto; qualquer membro que lê o space. Vai em `videoMediaId` de `POST /api/status/{id}/comment` e do `PUT` do comentário. - `lessonVideo` (Drops em aulas): vídeo gravado no app como a aula de um curso, até 350 MB; `spaceId` é o space do curso (módulo `courses`); só owner e admin. Vai em `videoMediaId` de `POST /api/courses/lesson` e `PUT /api/courses/lesson/{lessonId}` (aula `video`); o aluno o abre por `GET /api/courses/{courseId}/lesson/{lessonId}/media`. - `videoPoster`: a capa escolhida para um vídeo (JPEG, PNG ou WebP, até o limite de imagem); `spaceId` é o space do vídeo; só quem enviou o vídeo a liga, em `PUT /api/media/{id}/poster`. - `upvoteImage`: foto de um tópico de Upvote (JPEG, PNG ou WebP) até 50 MB; space `upvotes`; quem o `canCreate` permite; processada em fila como a da galeria (sem link até `ready`). Até 4 por tópico, em `mediaIds` de `POST /api/upvotes/spaces/{spaceId}/topics` e do `PATCH /api/upvotes/topics/{id}`. Abre para quem lê o tópico (visitante em space público incluído); tópico pendente, só para o autor e a equipe. - `channelImage`: foto de uma mensagem do Canal ou de uma resposta na thread (JPEG, PNG, WebP ou GIF, animado mantido) até 50 MB; space `channel`; quem o "Quem pode postar" (`canCreate`) permite; processada em fila como a da galeria (sem link até `ready`). Até 10 por mensagem, em `mediaIds` de `POST /api/channels/{spaceId}/messages` e de `POST /api/channels/messages/{id}/replies`; só quem enviou a liga. Abre para quem abre o space; a mensagem apagada leva a mídia junto (404). - `channelVideo`: vídeo de uma mensagem do Canal (Drop: gravado ou enviado, até 10 min, 350 MB, até 720p, por streaming); space `channel`; mesmas regras de `channelImage`. Um por mensagem. - `welcomeVideo`: vídeo das boas-vindas da comunidade (MP4, WebM, MOV) até 2 GB, sem `spaceId` (não mora em space); só owner e admin. Vai em `screens[].video.mediaId` de `PUT /api/welcome/settings`, e abre para todo perfil da comunidade.
Todo vídeo enviado ganha, em segundo plano, a duração (`durationSeconds`), a capa automática e até 6 quadros candidatos a capa (`coverCandidates` em `GET /api/media/{id}` para quem pode escolher; a escolha é em `PUT /api/media/{id}/cover`).
Drops: só quem enviou liga o vídeo ao item (nem a equipe liga o Drop de outra pessoa); com streaming nativo a conversão vai até **720p**. O vídeo abre para quem lê o item: em space com aprovação, pendente ou rejeitado, só para o autor e a equipe.
Imagem: o arquivo enviado pode ter até 50 MB (52428800 bytes); na confirmação ela é girada pela orientação, perde os metadados e fica com no máximo 4096 px no lado maior (o `size` devolvido é o da cópia guardada). JPEG aceita até ~268 megapixels; PNG, WebP e GIF (todos os quadros somados), até 50 megapixels; acima disso a confirmação devolve 400 (`dimensionsTooLarge`).
A mídia nova é **sempre privada**, com link assinado, mesmo em space público; o que foi enviado antes continua com a URL de sempre. Os limites de uso da comunidade só avisam (veja o `confirm`).
En-têtes
| Nom | Type | Description |
|---|---|---|
X-CommunityIdfacultatif | string (uuid) | ID da comunidade em que a operação acontece. Obrigatório na maioria dos endpoints com escopo de comunidade. |
Corps de la requête application/json
| Nom | Type | Description |
|---|---|---|
purposeobligatoire | contentVideo | eventRecording | galleryImage | classifiedImage | parcelPhoto | supportPhoto | statusVideo | contentCommentVideo | statusCommentVideo | lessonVideo | videoPoster | upvoteImage | channelImage | channelVideo | welcomeVideo | episodeAudio | episodeVideo | episodeCover | showCover | mediaEpisodeCommentVideo | |
spaceIdfacultatif | string (uuid) | Obrigatório em todo propósito, menos `welcomeVideo`. |
nameobligatoire | string | max 255 |
mimeTypeobligatoire | string | |
sizeobligatoire | integer | Bytes. · ≥ 1 |
Réponses
| Statut | Description |
|---|---|
200 | URL de envio. |
400 | Requisição inválida — falha de validação. |
401 | Token ausente, inválido ou expirado; token de outra comunidade (o `X-CommunityId` ou o `communityId` do corpo não é o do token); token antigo ou de uma sessão encerrada (troca de senha, convite aceito). Nesses casos a mensagem pede para entrar de novo (`auth.signInAgain`). |
403 | Autenticado, mas sem permissão para esta operação. |
404 | Recurso não encontrado. |
429 | Mais de 60 pedidos ou de 300 arquivos por hora para este perfil, ou 100 envios sem confirmar (`tooManyPending`). |
500 | Erro interno do servidor. |
Exemple curl
curl -X POST "https://api.memberfy.net/api/media/upload-url" \
-H "Authorization: Bearer $TOKEN" \
-H "X-CommunityId: $COMMUNITY_ID" \
-H "Content-Type: application/json" \
-d '{"purpose":"contentVideo","name":"string","mimeType":"video/mp4","size":1}'