# Ordem de criação

> O que precisa existir antes de cada chamada, de onde vem cada id, a sequência dos fluxos comuns e os erros que aparecem quando um passo é pulado.

Quase tudo na Memberfy depende de algo criado antes: a aula precisa do módulo, o módulo do curso, o curso do espaço. Chamar a API fora de ordem não estraga nada, mas cada chamada adiantada é recusada. Este guia mostra a ordem certa e o id que passa de uma chamada para a seguinte.

## O mapa de dependências

<div class="flow">
<div class="flow-row"><span class="flow-label">Estrutura e conteúdo</span><span class="flow-node">Comunidade</span><span class="flow-arrow">→</span><span class="flow-node">Seção</span><span class="flow-arrow">→</span><span class="flow-node">Espaço (módulo)</span><span class="flow-arrow">→</span><span class="flow-node">Post · Evento · Imagem</span></div>
<div class="flow-row"><span class="flow-label">Cursos</span><span class="flow-node">Espaço de Cursos</span><span class="flow-arrow">→</span><span class="flow-node">Curso</span><span class="flow-arrow">→</span><span class="flow-node">Módulo</span><span class="flow-arrow">→</span><span class="flow-node">Aula</span></div>
<div class="flow-row"><span class="flow-label">Venda</span><span class="flow-node">Recebimento aprovado</span><span class="flow-arrow">→</span><span class="flow-node">Vender e sacar</span></div>
<div class="flow-row"><span class="flow-label">Assinatura</span><span class="flow-node">Opção de cobrança</span><span class="flow-arrow">→</span><span class="flow-node">Plano</span><span class="flow-arrow">→</span><span class="flow-node">Adicionais do plano</span><span class="flow-arrow">→</span><span class="flow-node">Downsell</span></div>
<div class="flow-row"><span class="flow-label">Acesso</span><span class="flow-node">Plano ou produto</span><span class="flow-arrow">→</span><span class="flow-node">Acesso do espaço</span></div>
<div class="flow-row"><span class="flow-label">Desconto</span><span class="flow-node">Produtos</span><span class="flow-arrow">→</span><span class="flow-node">Cupom</span></div>
</div>

Lido de outro jeito:

| Para criar… | Precisa antes de… | E passa |
|---|---|---|
| Espaço | uma seção | `sectionId` |
| Post, evento, curso, imagem | um espaço | `spaceId` |
| Módulo de curso | um curso | `courseId` |
| Aula | um módulo | `moduleId` |
| Plano | as opções de cobrança (produtos `SUBSCRIPTION`) | `productIds` |
| Adicional no plano | o plano, e um produto mensal que não seja opção de plano | `addOnProductIds` |
| Acesso a um espaço por plano ou produto | o plano ou o produto | `access.subscriptionGroupIds`, `access.productIds` |
| Cupom só para alguns produtos | os produtos | `applicableProducts` |
| Qualquer venda ou saque | Informação Comercial e conta de recebimento aprovadas | — |

Em todas as chamadas abaixo vão `Authorization` e `X-CommunityId`. Ver [Autenticação](/api/autenticacao) e [X-CommunityId](/api/x-community-id).

## Curso

1. **Seção** (se ainda não houver): [`POST /api/sections`](/api/referencia/sections-spaces/post-sections) com `title` e `visibility`. Guarde `data.id` como `sectionId`.
2. **Espaço de Cursos**: [`POST /api/spaces`](/api/referencia/sections-spaces/post-spaces) com `sectionId`, `title` e `module: "courses"`. Guarde o `spaceId`.
3. **Curso**: [`POST /api/courses`](/api/referencia/courses/post-courses) com `communityId` (o mesmo do header), `spaceId`, `title`, `slug` e `level` (`beginner`, `intermediate`, `advanced`). Nasce como rascunho. Guarde o `courseId`.
4. **Módulos**: [`POST /api/courses/module`](/api/referencia/courses/post-courses-module) com `courseId` e `title`, um por módulo. Guarde cada `moduleId`.
5. **Aulas**: [`POST /api/courses/lesson`](/api/referencia/courses/post-courses-lesson) com `moduleId`, `title` e `type` (`text`, `image`, `video`, `link`).
6. **Publicar**: [`PUT /api/courses/{id}`](/api/referencia/courses/put-courses-by-id) com `status: "published"`. Só curso publicado aceita matrícula.

Para ajustar depois: [`PUT`](/api/referencia/courses/put-courses-module-by-module-id) e [`DELETE /api/courses/module/{moduleId}`](/api/referencia/courses/delete-courses-module-by-module-id) renomeiam, reordenam e excluem um módulo (com as aulas); [`PUT`](/api/referencia/courses/put-courses-lesson-by-lesson-id) e [`DELETE /api/courses/lesson/{lessonId}`](/api/referencia/courses/delete-courses-lesson-by-lesson-id) mudam título, tipo, duração e ordem de uma aula, levam a aula para outro módulo do mesmo curso (`moduleId`) e a excluem. Excluir guarda o progresso de quem já assistiu.

Para vender o curso, siga com um produto que libera o espaço (veja [Evento](#evento), passos 3 e 4, que valem igual).

## Mentoria

Uma turma com mural próprio, encontros e cobrança mensal. (Com a [duração do contrato](/monetizacao/duracao-do-contrato), a opção do passo 3 ganha `commitmentMonths`.)

1. **Espaço privado da turma**: [`POST /api/spaces`](/api/referencia/sections-spaces/post-spaces) com `module: "feed"` e `visibility: "private"`. Guarde o `spaceId`.
2. **Encontros**: [`POST /api/events`](/api/referencia/events/post-events), um por encontro, com `spaceId`, `title`, `slug`, `type: "online"`, `startTime` e `endTime`.
3. **Opção de cobrança**: [`POST /api/products`](/api/referencia/products/post-communities-by-community-id-products) com `type: "SUBSCRIPTION"`, `title`, `price`, `billingInterval: "MONTHLY"` e `allowedPaymentMethods`. Guarde o `id` do produto.
4. **Plano**: [`POST /api/subscription-groups`](/api/referencia/subscriptions/post-communities-by-community-id-subscription-groups) com `name` e `productIds: [<id do passo 3>]`. Guarde o `id` do plano.
5. **Liberar o espaço para o plano**: [`PUT /api/spaces/{id}`](/api/referencia/sections-spaces/put-spaces-by-id) com `access: { "subscriptionGroupIds": [<id do plano>] }`.

O passo 5 só funciona depois do 4: o plano precisa existir para ser citado no acesso.

## Evento

Um evento presencial com ingresso pago e aviso no Feed.

1. **Espaço de Eventos**: [`POST /api/spaces`](/api/referencia/sections-spaces/post-spaces) com `module: "events"`.
2. **Evento**: [`POST /api/events`](/api/referencia/events/post-events) com `spaceId`, `title`, `slug`, `type: "in_person"`, `startTime`, `endTime` e o endereço (`street`, `number`, `city`…).
3. **Ingresso**: [`POST /api/products`](/api/referencia/products/post-communities-by-community-id-products) com `type: "ONE_TIME"`, `price`, `hasStock: true` e `stockQuantity`. Depois, [publique](/api/referencia/products/post-communities-by-community-id-products-by-id-publish).
4. **Liberar o espaço para quem comprou**: [`PUT /api/spaces/{id}`](/api/referencia/sections-spaces/put-spaces-by-id) com `visibility: "private"` e `access: { "productIds": [<id do ingresso>] }`.
5. **Aviso fixado**: [`POST /api/content`](/api/referencia/content/post-content) no espaço do Feed, e [`PUT /api/feed/{type}/{id}/pin`](/api/referencia/feed/put-feed-by-type-by-id-pin) com o id do post.

## Plano com adicionais

1. **Opções de cobrança do plano**: um [`POST .../products`](/api/referencia/products/post-communities-by-community-id-products) por opção (Mensal, Anual), `type: "SUBSCRIPTION"`.
2. **O adicional**: outro `POST .../products`, `type: "SUBSCRIPTION"`, `billingInterval: "MONTHLY"`. Ele **não** entra em `productIds` de plano nenhum.
3. **Plano**: [`POST .../subscription-groups`](/api/referencia/subscriptions/post-communities-by-community-id-subscription-groups) com `productIds` do passo 1.
4. **Adicionais no plano**: [`PUT .../subscription-groups/{id}`](/api/referencia/subscriptions/put-communities-by-community-id-subscription-groups-by-id) com `addOnProductIds: [<id do passo 2>]`.

## Antes de vender: o recebimento

Uma ordem que vale para qualquer venda:

1. [`POST .../business-information`](/api/referencia/business/post-communities-by-community-id-business-information) e [`.../submit`](/api/referencia/business/post-communities-by-community-id-business-information-submit).
2. [`POST .../payout-settings`](/api/referencia/payouts/post-communities-by-community-id-payout-settings) e [`.../submit`](/api/referencia/payouts/post-communities-by-community-id-payout-settings-submit).
3. Esperar as duas aprovações (até 7 dias úteis). [`GET .../payout-settings/prerequisites`](/api/referencia/payouts/get-communities-by-community-id-payout-settings-prerequisites) diz o que falta.

Produtos, opções, planos, adicionais, cupons e ofertas de downsell podem ser criados e editados antes da aprovação: o produto nasce `DRAFT`, com a moeda do país da Informação Comercial (em qualquer status) ou `BRL` sem ela. Publicar ([`POST .../products/{id}/publish`](/api/referencia/products/post-communities-by-community-id-products-by-id-publish), ou `PUT .../products/{id}` com `status: ACTIVE`), o checkout e o saque esperam a aprovação. Uma Informação Comercial aprovada que é editada volta para `PENDING` e precisa de `.../submit` de novo; até a nova aprovação, o checkout recusa.

## Os erros de quem pulou um passo

| Chamada | Faltou | Resposta |
|---|---|---|
| `POST /api/spaces` | a seção | `400` · *Seção não encontrada ou não pertence a esta comunidade.* |
| `POST /api/spaces` (ou `PUT`) | a seção é mais fechada | `400` · *Este espaço não pode ser mais aberto que a seção "…", que é …* |
| `PUT /api/spaces/{id}` com `access` | o plano, produto ou grupo citado | `400` · *A concessão de acesso "…" não existe nesta comunidade.* (`param: access`) |
| `POST /api/courses` | o espaço | `400` · *ID do espaço é obrigatório.* ou *Espaço não encontrado ou não pertence a esta comunidade.* |
| `POST /api/courses/module` | o curso | `404` · *Curso não encontrado.* |
| `POST /api/courses/lesson` | o módulo | `404` · *Módulo não encontrado.* |
| `POST .../subscription-groups` | as opções de cobrança | `400` · *Produto não encontrado* |
| `PUT .../subscription-groups/{id}` com `addOnProductIds` | o produto do adicional, ou ele já é opção de um plano | `400` · *Um dos adicionais não existe nesta comunidade ou foi excluído.* / *Um produto que é opção de cobrança de um plano não pode ser adicional de outro.* |
| Configuração do checkout | o recebimento aprovado | `400` · *Configuração de pagamento não foi realizada para esta comunidade* |
| `POST .../products/{id}/publish` (ou `PUT` com `status: ACTIVE`) | a Informação Comercial aprovada | `403` · *Para publicar e começar a vender, a comunidade precisa ter as informações comerciais aprovadas…* |
| `POST .../products/{id}/publish` | o produto na moeda do país aprovado | `400` · *Este produto está em … mas a moeda das informações comerciais aprovadas é …* (`param: currency`) |
| `POST /api/checkout` | a Informação Comercial aprovada | `403` · *A comunidade deve ter informações de negócio aprovadas para habilitar produtos pagos* |
| `POST .../payouts` | saldo para o valor e a taxa | `400` · *Saldo insuficiente. Disponível: …* |
| Qualquer uma | o header | `400` · *X-CommunityId é obrigatório* |

Algumas validações de formato ainda respondem em inglês (como *Valid course ID is required* quando o id não é um UUID).

## Dicas

- **Guarde cada id** que volta em `data.id`: é ele que a chamada seguinte pede.
- **Envie o mesmo `communityId`** no corpo (quando a rota pede) e no header.
- **Repetir não desfaz**: se uma sequência parar no meio, continue do passo que falhou, em vez de recomeçar (recomeçar cria duplicados).
- No [MCP](/mcp/ferramentas), as ferramentas compostas fazem essa ordem sozinhas.
