Aller au contenu

Cria ou executa events

POST/api/events

Auth
Jeton requis
Qui peut l’appeler:
owner
admin
moderator
Clé d’API:
events:write
X-CommunityId
X-CommunityId Envoyez le X-CommunityId de la communauté où l’opération a lieu.
Les descriptions des endpoints viennent directement de la spécification de l’API et sont en portugais pour l’instant. L’interface autour est traduite.

Sujeito a verificação de papel (RBAC). Além disso, respeita o `canCreate` do space: `staff` aceita owner, admin, moderator e finance; `admins` aceita owner e admin; `anyone` não restringe. Fora da regra, 403 com `errors[0].param = "spaceId"`. SuperAdmin sempre passa.

Na mesma transação nasce o produto do evento (`kind: event`, rascunho gratuito, preço `0`, moeda da comunidade); a resposta traz `data.product` (`{ id, kind, status, price, currency, capacity, available, soldOut }`) para o botão "Preço e venda" abrir `PUT /api/products/{id}`. A capacidade (vagas) se define nesse produto com `capacity`. As listas e o detalhe de evento trazem o mesmo `product` (`capacity` e `available` só para a equipe; os demais veem `soldOut`); o detalhe acrescenta `access`, `canEnter` e `waitlist`. O produto do evento é o primeiro tipo de ingresso ("Ingresso", com um lote); `product` é o tipo padrão (o dos assinantes) e traz `ticketTypesCount`. Os tipos e lotes ficam em `GET /api/events/{id}/ticket-types`.

**Certificado:** o bloco opcional `certificate` `{ enabled, templateId?, text? }` (`EventCertificateInput`) liga o certificado para quem confirmar presença. Só owner e admin o enviam (moderador, 403). Ligar exige `endTime` (400). A resposta traz `data.certificate` (só para owner e admin) e `data.issuesCertificate`. Fim igual ou anterior ao início, 400.

**Rascunho (padrão, editor de eventos):** sem `publish`, o evento nasce `status: DRAFT`. Só `spaceId` é obrigatório; `title`, `startTime` e `slug` são opcionais (o servidor gera o slug do título, ou `event`, e o slug acompanha o título enquanto for rascunho). O rascunho **não dispara nada**: sem item no feed, sem aviso por e-mail, sem aviso em tempo real, sem moderação, sem pontos e sem o webhook `event.created`; só a equipe o vê. `data.emailNotice` vem `{ scheduled: false, reason: "draft" }` e `data.readiness` traz a lista "Para publicar" (`EventReadiness`). Publicar: `POST /api/events/{id}/publish`.

**`publish: true`** mantém o comportamento antigo (cria e publica na hora; `slug`, `title` e `startTime` obrigatórios): moderação do espaço, feed, `event.created` e, com `notifyByEmail` (padrão ligado) e quem cria sendo owner, admin ou moderador, o aviso por e-mail a quem pode ver o evento e tem a categoria "Eventos" ligada, 10 minutos depois (nunca para evento já passado; em moderação, só quando aprovado). A resposta traz `data.emailNotice` (`EmailNoticeResult`).

En-têtes

NomTypeDescription
X-CommunityIdfacultatifstring (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

NomTypeDescription
publishfacultatifboolean`true` cria e publica na hora (o comportamento de antes dos rascunhos; exige `slug`, `title` e `startTime`). Sem ele, nasce rascunho.
spaceIdobligatoirestring (uuid)O espaço do evento (obrigatório).
slugfacultatifstringOpcional no rascunho (gerado do título); obrigatório com `publish: true`.
titlefacultatifstringOpcional no rascunho; obrigatório com `publish: true`.
startTimefacultatifstringInício. Sem fuso (`2026-10-20T19:00:00`), é o horário da comunidade; com `Z` ou deslocamento (`2026-10-20T22:00:00Z`, `2026-10-20T19:00:00-03:00`), é esse instante. Obrigatório com `publish: true` (sem ele, 400 com `errors[].param = startTime`); no rascunho, opcional até publicar.
endTimefacultatifstringFim, com a mesma regra de fuso do `startTime`. Tem de ser depois dele: igual ou antes, 400 com `errors[].param = endTime`.
certificatefacultatifobjectCertificado de evento: bloco opcional de `POST` e `PUT /api/events`. Quem confirma presença (`going`) até o fim do evento recebe o certificado cerca de 1 hora depois. **Ausente** não mexe em nada: gravar outros campos do evento nunca muda o certificado, e evento novo sem o bloco nasce desligado. `certificateEnabledAt` é do servidor e **não** é enviado: ele grava na virada de desligado para ligado (religar grava de novo) e zera ao desligar; só eventos que terminam a partir dele emitem, sem emissão retroativa. Desligar mantém o modelo e o texto. **Só owner e admin** (e SuperAdmin) enviam o bloco: moderador e membro recebem 403, mesmo que possam editar o evento. Ligar exige `endTime` (400 sem ele, `errors[].param = certificate.enabled`).
certificate.enabledfacultatifbooleanLiga ou desliga. Ausente mantém o estado atual (desligado num evento novo).
certificate.templateIdfacultatifstring (uuid)Modelo do módulo Certificados. Tem de ser ATIVO e da mesma comunidade: de outra comunidade, 404; rascunho, arquivado ou apagado, 400 (`errors[].param = certificate.templateId`). Ausente mantém; `null` ou sem modelo vale o padrão do sistema (criado sob demanda, com o espaço Certificados se a comunidade não tem um).
certificate.textfacultatifstringTexto do certificado: texto simples (sem HTML), com as variáveis `{nome}`, `{assunto}` (o título do evento), `{data}` (a data do evento no fuso do evento, ou o da comunidade: "12 de outubro de 2026"; em dias diferentes "12 a 14 de outubro de 2026") e `{cargaHoraria}`; `[...]` entre colchetes some quando a variável dentro está vazia. Vazio ou `null` usa `certificate.defaultText`. · max 5000
checkInEnabledfacultatifbooleanUsar check-in. Cada "Vou" (ou compra) tem um ingresso com QR e código (`GET /api/events/{id}/my-ticket`), a equipe faz o check-in na porta (`/api/events/{id}/check-in`) e, em evento online ou híbrido, abrir a transmissão ao vivo conta presença. Com ele ligado, o certificado automático do evento vai só para quem fez check-in.
checkInBadgeIdfacultatifstring (uuid)"Badge ao fazer check-in", já na criação (igual ao `PUT /api/events/{id}`): um badge do catálogo da comunidade, só owner e admin (moderador ou financeiro que o enviam, 403). Badge que não existe ou de outra comunidade, 422 no campo. A resposta traz `data.checkInBadge`.
notifyByEmailfacultatifbooleanAvisar por e-mail (regras em NotifyByEmailInput). Só vale com `publish: true`; no rascunho, vai no `POST /api/events/{id}/publish`.
typefacultatifonline | hybrid | in_personType must be online, hybrid, or in_person
locationfacultatifstringLocation must be a string
placeIdfacultatifstringPlace ID must be a string
streetfacultatifstringStreet must be a string
numberfacultatifstringNumber must be a string
neighborhoodfacultatifstringNeighborhood must be a string
cityfacultatifstringCity must be a string
statefacultatifstringState must be a string
countryfacultatifstringCountry must be a string
postalCodefacultatifstringPostal code must be a string
latitudefacultatifnumberLatitude must be a number
longitudefacultatifnumberLongitude must be a number
streamingUrlfacultatifstring (uri)Streaming URL must be valid
streamingServicefacultatifyoutube | vimeo | muxStreaming service must be youtube, vimeo, or mux
bannerUrlfacultatifstring (uri)Banner URL must be valid
featuredImageUrlfacultatifstring (uri)Featured image URL must be valid
videoTeaserUrlfacultatifstring (uri)Video teaser URL must be valid
hostIdsfacultatif—[]hostIds must be an array
hostIds.*facultatifstring (uuid)Each hostId must be a valid UUID
organizerIdsfacultatif—[]organizerIds must be an array
organizerIds.*facultatifstring (uuid)Each organizerId must be a valid UUID
timezonefacultatifstringFuso IANA do evento (ex.: America/Sao_Paulo). Opcional: sem ele, vale o fuso do país da comunidade. Os horários enviados são lidos nesse fuso. Validado como fuso IANA: `"Lua/Base"` → 400 com `errors[].param = timezone` (também no `PUT` e no `PATCH`).
audiencefacultatifstringAudience must be a string
visibilityfacultatifpublic | members | plan | private`public` (qualquer pessoa), `members` (membros da comunidade), `plan` (**assinantes** de um plano, e a equipe) ou `private` (só a equipe: owner, admin, moderador, financeiro). O "Privado" das telas é `private`; `plan` abre o evento para quem assina.
bannerFocalXfacultatifnumberPonto focal da capa, horizontal (0 = esquerda, 1 = direita). `null` limpa. · ≥ 0, ≤ 1
bannerFocalYfacultatifnumberPonto focal da capa, vertical (0 = topo, 1 = base). · ≥ 0, ≤ 1
featuredFocalXfacultatifnumberPonto focal da imagem do card, horizontal. · ≥ 0, ≤ 1
featuredFocalYfacultatifnumberPonto focal da imagem do card, vertical. · ≥ 0, ≤ 1
categoryfacultatiflivestream | workshop | webinar | meetup | demo | event | conference | festival | mentorship | panel | masterclass | bootcamp | networking | round_table | pitchTipo do evento. Fora da lista: 400 com `errors` no campo `category` (antes era 500).

Réponses

StatutDescription
201Evento criado (rascunho, ou publicado com `publish: true`). Traz `status`, `publishedAt`, `updatedAt` e os pontos focais; `data.certificate` só para owner e admin.
400Requisição inválida — falha de validação.
401Token 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`).
403Autenticado, mas sem permissão para esta operação.
404Recurso não encontrado.
500Erro interno do servidor.

Exemple curl

curl -X POST "https://api.memberfy.net/api/events" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-CommunityId: $COMMUNITY_ID" \
  -H "Content-Type: application/json" \
  -d '{"spaceId":"00000000-0000-0000-0000-000000000000"}'