# Ordine di creazione

> Che cosa deve esistere prima di ogni chiamata, da dove arriva ogni id, la sequenza dei flussi più comuni e gli errori che compaiono quando si salta un passaggio.

Quasi tutto su Memberfy dipende da qualcosa creato prima: la lezione ha bisogno del modulo, il modulo del corso, il corso dello spazio. Chiamare l'API fuori ordine non rompe nulla, ma ogni chiamata anticipata viene rifiutata. Questa guida mostra l'ordine giusto e l'id che passa da una chiamata alla successiva.

## La mappa delle dipendenze

<div class="flow">
<div class="flow-row"><span class="flow-label">Struttura e contenuti</span><span class="flow-node">Community</span><span class="flow-arrow">→</span><span class="flow-node">Sezione</span><span class="flow-arrow">→</span><span class="flow-node">Spazio (modulo)</span><span class="flow-arrow">→</span><span class="flow-node">Post · Evento · Immagine</span></div>
<div class="flow-row"><span class="flow-label">Corsi</span><span class="flow-node">Spazio Corsi</span><span class="flow-arrow">→</span><span class="flow-node">Corso</span><span class="flow-arrow">→</span><span class="flow-node">Modulo</span><span class="flow-arrow">→</span><span class="flow-node">Lezione</span></div>
<div class="flow-row"><span class="flow-label">Vendita</span><span class="flow-node">Conto di accredito approvato</span><span class="flow-arrow">→</span><span class="flow-node">Vendere e prelevare</span></div>
<div class="flow-row"><span class="flow-label">Abbonamento</span><span class="flow-node">Opzione di fatturazione</span><span class="flow-arrow">→</span><span class="flow-node">Piano</span><span class="flow-arrow">→</span><span class="flow-node">Componenti aggiuntivi del piano</span><span class="flow-arrow">→</span><span class="flow-node">Downsell</span></div>
<div class="flow-row"><span class="flow-label">Accesso</span><span class="flow-node">Piano o prodotto</span><span class="flow-arrow">→</span><span class="flow-node">Accesso allo spazio</span></div>
<div class="flow-row"><span class="flow-label">Sconto</span><span class="flow-node">Prodotti</span><span class="flow-arrow">→</span><span class="flow-node">Coupon</span></div>
</div>

Letto in un altro modo:

| Per creare… | Serve prima… | E si passa |
|---|---|---|
| Spazio | una sezione | `sectionId` |
| Post, evento, corso, immagine | uno spazio | `spaceId` |
| Modulo del corso | un corso | `courseId` |
| Lezione | un modulo | `moduleId` |
| Piano | le opzioni di fatturazione (prodotti `SUBSCRIPTION`) | `productIds` |
| Componente aggiuntivo del piano | il piano, e un prodotto mensile che non sia un'opzione di un piano | `addOnProductIds` |
| Accesso a uno spazio per piano o prodotto | il piano o il prodotto | `access.subscriptionGroupIds`, `access.productIds` |
| Coupon valido solo per alcuni prodotti | i prodotti | `applicableProducts` |
| Qualsiasi vendita o prelievo | Informazioni Aziendali e conto di accredito approvati | — |

In tutte le chiamate qui sotto si inviano `Authorization` e `X-CommunityId`. Vedi [Autenticazione](/api/autenticacao) e [X-CommunityId](/api/x-community-id).

## Corso

1. **Sezione** (se non c'è ancora): [`POST /api/sections`](/api/referencia/sections-spaces/post-sections) con `title` e `visibility`. Conserva `data.id` come `sectionId`.
2. **Spazio Corsi**: [`POST /api/spaces`](/api/referencia/sections-spaces/post-spaces) con `sectionId`, `title` e `module: "courses"`. Conserva lo `spaceId`.
3. **Corso**: [`POST /api/courses`](/api/referencia/courses/post-courses) con `communityId` (lo stesso dell'header), `spaceId`, `title`, `slug` e `level` (`beginner`, `intermediate`, `advanced`). Nasce come bozza. Conserva il `courseId`.
4. **Moduli**: [`POST /api/courses/module`](/api/referencia/courses/post-courses-module) con `courseId` e `title`, uno per modulo. Conserva ogni `moduleId`.
5. **Lezioni**: [`POST /api/courses/lesson`](/api/referencia/courses/post-courses-lesson) con `moduleId`, `title` e `type` (`text`, `image`, `video`, `link`).
6. **Pubblicare**: [`PUT /api/courses/{id}`](/api/referencia/courses/put-courses-by-id) con `status: "published"`. Solo un corso pubblicato accetta iscrizioni.

Per sistemare in seguito: [`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) rinominano, riordinano ed eliminano un modulo (con le sue lezioni); [`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) cambiano titolo, tipo, durata e ordine di una lezione, la spostano in un altro modulo dello stesso corso (`moduleId`) e la eliminano. L'eliminazione conserva i progressi di chi l'aveva già seguita.

Per vendere il corso, prosegui con un prodotto che apre lo spazio (vedi [Evento](#evento), passaggi 3 e 4, che valgono allo stesso modo).

## Mentoring

Una classe con una bacheca propria, incontri e addebito mensile. (Con la [durata del contratto](/monetizacao/duracao-do-contrato), l'opzione del passaggio 3 riceve `commitmentMonths`.)

1. **Spazio privato della classe**: [`POST /api/spaces`](/api/referencia/sections-spaces/post-spaces) con `module: "feed"` e `visibility: "private"`. Conserva lo `spaceId`.
2. **Incontri**: [`POST /api/events`](/api/referencia/events/post-events), uno per incontro, con `spaceId`, `title`, `slug`, `type: "online"`, `startTime` ed `endTime`.
3. **Opzione di fatturazione**: [`POST /api/products`](/api/referencia/products/post-communities-by-community-id-products) con `type: "SUBSCRIPTION"`, `title`, `price`, `billingInterval: "MONTHLY"` e `allowedPaymentMethods`. Conserva l'`id` del prodotto.
4. **Piano**: [`POST /api/subscription-groups`](/api/referencia/subscriptions/post-communities-by-community-id-subscription-groups) con `name` e `productIds: [<id del passaggio 3>]`. Conserva l'`id` del piano.
5. **Aprire lo spazio al piano**: [`PUT /api/spaces/{id}`](/api/referencia/sections-spaces/put-spaces-by-id) con `access: { "subscriptionGroupIds": [<id del piano>] }`.

Il passaggio 5 funziona solo dopo il 4: il piano deve esistere per poter essere indicato nell'accesso.

## Evento

Un evento in presenza con biglietto a pagamento e avviso nel Feed.

1. **Spazio Eventi**: [`POST /api/spaces`](/api/referencia/sections-spaces/post-spaces) con `module: "events"`.
2. **Evento**: [`POST /api/events`](/api/referencia/events/post-events) con `spaceId`, `title`, `slug`, `type: "in_person"`, `startTime`, `endTime` e l'indirizzo (`street`, `number`, `city`…).
3. **Biglietto**: [`POST /api/products`](/api/referencia/products/post-communities-by-community-id-products) con `type: "ONE_TIME"`, `price`, `hasStock: true` e `stockQuantity`. Poi [pubblicalo](/api/referencia/products/post-communities-by-community-id-products-by-id-publish).
4. **Aprire lo spazio a chi ha acquistato**: [`PUT /api/spaces/{id}`](/api/referencia/sections-spaces/put-spaces-by-id) con `visibility: "private"` e `access: { "productIds": [<id del biglietto>] }`.
5. **Avviso fissato**: [`POST /api/content`](/api/referencia/content/post-content) nello spazio Feed, e [`PUT /api/feed/{type}/{id}/pin`](/api/referencia/feed/put-feed-by-type-by-id-pin) con l'id del post.

## Piano con componenti aggiuntivi

1. **Opzioni di fatturazione del piano**: un [`POST .../products`](/api/referencia/products/post-communities-by-community-id-products) per opzione (Mensile, Annuale), `type: "SUBSCRIPTION"`.
2. **Il componente aggiuntivo**: un altro `POST .../products`, `type: "SUBSCRIPTION"`, `billingInterval: "MONTHLY"`. **Non** entra nei `productIds` di nessun piano.
3. **Piano**: [`POST .../subscription-groups`](/api/referencia/subscriptions/post-communities-by-community-id-subscription-groups) con i `productIds` del passaggio 1.
4. **Componenti aggiuntivi nel piano**: [`PUT .../subscription-groups/{id}`](/api/referencia/subscriptions/put-communities-by-community-id-subscription-groups-by-id) con `addOnProductIds: [<id del passaggio 2>]`.

## Prima di vendere: il conto di accredito

Un ordine che vale per qualsiasi vendita:

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. Attendere le due approvazioni (fino a 7 giorni lavorativi). [`GET .../payout-settings/prerequisites`](/api/referencia/payouts/get-communities-by-community-id-payout-settings-prerequisites) indica che cosa manca.

Prodotti, opzioni, piani, componenti aggiuntivi, coupon e offerte di downsell si possono creare e modificare prima dell'approvazione: il prodotto nasce `DRAFT`, nella valuta del paese delle Informazioni Aziendali (in qualsiasi stato) oppure in `BRL` se non ci sono. La pubblicazione ([`POST .../products/{id}/publish`](/api/referencia/products/post-communities-by-community-id-products-by-id-publish), oppure `PUT .../products/{id}` con `status: ACTIVE`), il checkout e il prelievo aspettano l'approvazione. Delle Informazioni Aziendali approvate che vengono modificate tornano a `PENDING` e richiedono di nuovo `.../submit`; fino alla nuova approvazione, il checkout rifiuta.

## Gli errori di chi salta un passaggio

| Chiamata | Che cosa mancava | Risposta |
|---|---|---|
| `POST /api/spaces` | la sezione | `400` · *Seção não encontrada ou não pertence a esta comunidade.* |
| `POST /api/spaces` (o `PUT`) | la sezione è più chiusa | `400` · *This space cannot be more open than the section "…", which is …* |
| `PUT /api/spaces/{id}` con `access` | il piano, prodotto o gruppo indicato | `400` · *The access grant "…" does not exist in this community.* (`param: access`) |
| `POST /api/courses` | lo spazio | `400` · *ID do espaço é obrigatório.* oppure *Espaço não encontrado ou não pertence a esta comunidade.* |
| `POST /api/courses/module` | il corso | `404` · *Course not found* |
| `POST /api/courses/lesson` | il modulo | `404` · *Module not found* |
| `POST .../subscription-groups` | le opzioni di fatturazione | `400` · *Prodotto non trovato* |
| `PUT .../subscription-groups/{id}` con `addOnProductIds` | il prodotto del componente aggiuntivo, oppure è già un'opzione di un piano | `400` · *Uno dei componenti aggiuntivi non esiste in questa community o è stato eliminato.* / *Un prodotto che è un'opzione di pagamento di un piano non può essere un componente aggiuntivo di un altro.* |
| Configurazione del checkout | il conto di accredito approvato | `400` · *Configuração de pagamento não foi realizada para esta comunidade* |
| `POST .../products/{id}/publish` (o `PUT` con `status: ACTIVE`) | le Informazioni Aziendali approvate | `403` · *Per pubblicare e iniziare a vendere, la community deve avere le informazioni aziendali approvate…* |
| `POST .../products/{id}/publish` | il prodotto nella valuta del paese approvato | `400` · *Questo prodotto è in …, ma la valuta delle informazioni aziendali approvate è …* (`param: currency`) |
| `POST /api/checkout` | le Informazioni Aziendali approvate | `403` · *La community deve avere informazioni aziendali approvate per abilitare prodotti a pagamento* |
| `POST .../payouts` | saldo sufficiente per l'importo e la commissione | `400` · *Saldo insufficiente. Disponibile: …* |
| Qualsiasi | l'header | `400` · *X-CommunityId é obrigatório* |

Alcuni messaggi arrivano ancora in inglese o in portoghese, qualunque sia l'`Accept-Language` (come *Valid course ID is required* quando l'id non è un UUID). Basati sullo status code e su `param`, non sul testo.

## Consigli

- **Conserva ogni id** che torna in `data.id`: è quello che chiede la chiamata successiva.
- **Invia lo stesso `communityId`** nel corpo (quando la rotta lo chiede) e nell'header.
- **Ripetere non annulla**: se una sequenza si interrompe a metà, riprendi dal passaggio fallito invece di ricominciare (ricominciare crea duplicati).
- Nell'[MCP](/mcp/ferramentas), gli strumenti composti seguiranno questo ordine da soli.
