# Início rápido Em quatro passos você sai do zero e lê dados reais da sua empresa: criar a credencial, pedir o token, conferir quem você é e consultar eventos. Tudo leva poucos minutos. ## Antes de começar Você precisa de uma empresa nos planos Premium ou Enterprise e de um usuário com a permissão **Gerenciar a API pública e as chaves MCP**. Os detalhes estão em [Introdução](https://developers.festero.com.br/introducao.md#quem-pode-criar-uma-credencial). ## 1. Criar a credencial 1. No Festero, abra **API do Festero** no menu lateral. 2. Clique em **Nova credencial**. 3. Dê um nome que ajude você a reconhecê-la depois (até 80 caracteres), por exemplo `Integração com o ERP`. 4. Marque os **conjuntos de dados** que ela pode ler. Para este guia, marque **Eventos**. 5. Clique em **Criar credencial**. O Festero mostra então quatro valores. Copie todos: | Valor | Para que serve | |---|---| | `client_id` | Identifica a credencial. Não é secreto. | | `client_secret` | A senha da credencial. | | Endpoint do token | `https://auth.festero.com.br/oauth2/token` | | Parâmetro `scope` | Os escopos da credencial no formato do pedido de token, por exemplo `festero-api/events:read`. | > **Atenção**: Guarde o segredo agora > > O `client_secret` aparece **uma única vez**. Depois de fechar a janela, não é possível vê-lo de novo. Se perder, crie outra credencial. Ao fechar, o Festero ainda pergunta se você copiou. A credencial nasce com o status **Ativando** e pode levar alguns minutos para ficar **Ativa**. A lista na tela se atualiza sozinha. Faça os testes abaixo só depois que ela estiver ativa. ## 2. Pedir o token A API usa o fluxo *client credentials* do OAuth 2.0: você troca o `client_id` e o `client_secret` por um token de acesso. O token vale por **60 minutos**. No `curl`, `$CLIENT_ID` e `$CLIENT_SECRET` são variáveis do seu terminal com os valores da credencial, e nos passos seguintes `$ACCESS_TOKEN` é o `access_token` da resposta. **curl** ```bash curl -X POST https://auth.festero.com.br/oauth2/token \ -u "$CLIENT_ID:$CLIENT_SECRET" \ -d "grant_type=client_credentials" \ -d "scope=festero-api/events:read" ``` **JavaScript** ```js const basic = Buffer.from(`${process.env.FESTERO_CLIENT_ID}:${process.env.FESTERO_CLIENT_SECRET}`).toString('base64') const resposta = await fetch('https://auth.festero.com.br/oauth2/token', { method: 'POST', headers: { Authorization: `Basic ${basic}`, 'Content-Type': 'application/x-www-form-urlencoded' }, body: new URLSearchParams({ grant_type: 'client_credentials', scope: 'festero-api/events:read' }), }) const { access_token, expires_in } = await resposta.json() ``` **Python** ```python import os import requests resposta = requests.post( "https://auth.festero.com.br/oauth2/token", auth=(os.environ["FESTERO_CLIENT_ID"], os.environ["FESTERO_CLIENT_SECRET"]), data={"grant_type": "client_credentials", "scope": "festero-api/events:read"}, ) corpo = resposta.json() access_token = corpo["access_token"] ``` **C#** ```csharp using System.Net.Http.Headers; using System.Text; using System.Text.Json; var clientId = Environment.GetEnvironmentVariable("FESTERO_CLIENT_ID"); var clientSecret = Environment.GetEnvironmentVariable("FESTERO_CLIENT_SECRET"); using var http = new HttpClient(); var basic = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{clientId}:{clientSecret}")); var pedido = new HttpRequestMessage(HttpMethod.Post, "https://auth.festero.com.br/oauth2/token") { Headers = { Authorization = new AuthenticationHeaderValue("Basic", basic) }, Content = new FormUrlEncodedContent(new Dictionary { ["grant_type"] = "client_credentials", ["scope"] = "festero-api/events:read", }), }; var resposta = await http.SendAsync(pedido); resposta.EnsureSuccessStatusCode(); using var corpo = JsonDocument.Parse(await resposta.Content.ReadAsStringAsync()); var accessToken = corpo.RootElement.GetProperty("access_token").GetString(); ``` A resposta traz o token e o tempo de validade, em segundos: ```json { "access_token": "eyJraWQiOi...", "expires_in": 3600, "token_type": "Bearer" } ``` Para pedir mais de um conjunto de dados, separe os escopos por espaço: `festero-api/events:read festero-api/quotes:read`. Quando o espaço vai num corpo de formulário no `curl`, codifique-o como `%20`. Veja todos os escopos em [Autenticação](https://developers.festero.com.br/autenticacao.md#escopos). ## 3. Conferir quem você é `GET /v1/me` não exige escopo e devolve a credencial, a empresa e o plano. É a forma mais barata de testar o token. **curl** ```bash curl https://platform.festero.com.br/v1/me \ -H "Authorization: Bearer $ACCESS_TOKEN" ``` **JavaScript** ```js const me = await fetch('https://platform.festero.com.br/v1/me', { headers: { Authorization: `Bearer ${access_token}` }, }) console.log(await me.json()) ``` **Python** ```python me = requests.get( "https://platform.festero.com.br/v1/me", headers={"Authorization": f"Bearer {access_token}"}, ) print(me.json()) ``` **C#** ```csharp var pedidoMe = new HttpRequestMessage(HttpMethod.Get, "https://platform.festero.com.br/v1/me"); pedidoMe.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); var me = await http.SendAsync(pedidoMe); Console.WriteLine(await me.Content.ReadAsStringAsync()); ``` ```json { "credentialId": "7c9e6679-7425-40de-944b-e07fc1f90ae7", "workspaceId": "0f8fad5b-d9cb-469f-a165-70867728950e", "scopes": ["events:read"], "tier": "PREMIUM", "authKind": "jwt" } ``` Se a resposta for `401` ou `403`, veja o campo `code` em [Erros](https://developers.festero.com.br/errors.md). Logo depois de criar a credencial, `credential_revoked` costuma significar que ela ainda está **Ativando**. ## 4. Consultar eventos Agora uma consulta de verdade. Os cinco eventos mais antigos por data de alteração: ```bash curl "https://platform.festero.com.br/v1/events?limit=5" \ -H "Authorization: Bearer $ACCESS_TOKEN" ``` ```json { "data": [ { "id": "b7e2c4a1-95d3-4f08-a6b2-1c8d3e5f7a90", "title": "Casamento Camila e Rafael", "status": "upcoming", "kind": "conventional", "eventType": { "id": "5d1a8c33-7e42-49b6-8f10-c2a9b4d6e871", "name": "Casamento" }, "client": { "id": "9a3e7d52-1b68-4c04-b7f9-e0d2a5c8316b", "name": "Camila Duarte" }, "eventDate": "2027-03-20", "eventTime": "18:00", "durationHours": 5, "guestCount": 150, "city": "Salvador", "state": "BA", "isRental": false, "quoteId": "e4f6a9b2-3c71-4d85-9b0e-7a1c5d8f2634", "totalAmount": { "amount": 42800.00, "currency": "BRL" }, "discount": { "amount": 1500.00, "currency": "BRL" }, "travelFee": null, "contractedAt": "2026-10-10T20:15:31-03:00", "createdAt": "2026-10-08T10:12:40-03:00", "updatedAt": "2026-10-10T20:15:31-03:00" } ], "nextCursor": "eyJ0IjozOTU0..." } ``` A lista foi abreviada aqui: a resposta real traz até 5 itens em `data`. Quando `nextCursor` vem preenchido, há mais resultados: repita a chamada com `cursor=`. Veja [Paginação e datas](https://developers.festero.com.br/paginacao.md). Todos os campos de evento estão em [Eventos](https://developers.festero.com.br/api/eventos.md). ## Exemplo completo O código abaixo guarda o token até perto de vencer, percorre todas as páginas e imprime os eventos de novembro de 2026. Troque `events:read` pelos escopos da sua credencial. ```js const TOKEN_URL = 'https://auth.festero.com.br/oauth2/token' const API = 'https://platform.festero.com.br' let token = null // { valor, venceEm } async function obterToken() { // Reaproveita o token até 1 minuto antes de vencer: pedir um por chamada é caro e limitado. if (token && Date.now() < token.venceEm - 60_000) return token.valor const basic = Buffer.from(`${process.env.FESTERO_CLIENT_ID}:${process.env.FESTERO_CLIENT_SECRET}`).toString('base64') const resposta = await fetch(TOKEN_URL, { method: 'POST', headers: { Authorization: `Basic ${basic}`, 'Content-Type': 'application/x-www-form-urlencoded' }, body: new URLSearchParams({ grant_type: 'client_credentials', scope: 'festero-api/events:read' }), }) if (!resposta.ok) throw new Error(`Falha ao pedir o token: HTTP ${resposta.status}`) const corpo = await resposta.json() token = { valor: corpo.access_token, venceEm: Date.now() + corpo.expires_in * 1000 } return token.valor } async function festero(caminho, parametros = {}) { const url = new URL(caminho, API) for (const [nome, valor] of Object.entries(parametros)) url.searchParams.set(nome, valor) const resposta = await fetch(url, { headers: { Authorization: `Bearer ${await obterToken()}` } }) if (!resposta.ok) { const problema = await resposta.json().catch(() => null) throw new Error(`HTTP ${resposta.status} ${problema?.code ?? ''} (requestId ${problema?.requestId ?? 'n/d'})`) } return resposta.json() } let cursor do { const pagina = await festero('/v1/events', { eventDateFrom: '2026-11-01', eventDateTo: '2026-11-30', limit: 100, ...(cursor && { cursor }), }) for (const evento of pagina.data) console.log(evento.eventDate, evento.title, evento.status) cursor = pagina.nextCursor } while (cursor) ``` ## Próximos passos - [Autenticação](https://developers.festero.com.br/autenticacao.md): escopos, validade da credencial, rotação e revogação. - [Limites de uso](https://developers.festero.com.br/limites.md): quantas chamadas cada plano permite. - [Erros](https://developers.festero.com.br/errors.md): o que cada `code` significa e o que fazer. - [Webhooks](https://developers.festero.com.br/webhooks.md): receba avisos em vez de consultar de tempos em tempos. - [Referência interativa](https://developers.festero.com.br/referencia/): teste qualquer rota no navegador.