# Referência da Listings API

`PUT /api/listings` cria ou atualiza um listing completo em uma única chamada atômica: a API, seus endpoints, o segredo de origem, planos, FAQs e APIs vinculadas. Ou tudo é salvo, ou nada é. É isso que as ferramentas MCP `provider_*` usam por baixo dos panos, e você pode chamá-la diretamente de scripts ou CI.

## Acesso

- Qualquer conta com **e-mail verificado**. Contas não verificadas ou bloqueadas recebem `403`.
- Autentique-se com sua [chave de API](https://zylalabs.com/pt/docs/api-keys): `Authorization: Bearer YOUR_API_KEY`.
- Limites de taxa por conta: 30 upserts e 120 leituras por minuto.
- Novos listings contam para a [cota de novas APIs](https://zylalabs.com/pt/docs/quality-rules). Atualizações nunca contam.

## Endpoints

| Método | Caminho | Finalidade |
|---|---|---|
| PUT | `/api/listings` | Cria ou atualiza um listing (ou o exclui com `"delete": true`) |
| GET | `/api/listings` | Seus listings (`status`, `page`, `per_page`) |
| GET | `/api/listings/{product_key}` | Definição completa de um listing (nunca o segredo de origem) |
| GET | `/api/listings/me` | Sua conta, limites, nomes de planos válidos e tipos de parâmetro |
| GET | `/api/listings/categories` | Ids de categoria |

## Exemplo

```bash
curl -X PUT https://zylalabs.com/api/listings \
  -H "Authorization: Bearer $ZYLA_API_KEY" \
  -H "Content-Type: application/json" \
  -d @listing.json
```

`listing.json`:

```json
{
  "product_key": "trustpilot-api",
  "publish": true,
  "api": {
    "name": "Trustpilot Reviews API",
    "short_description": "Retrieve Trustpilot company reviews, ratings and reviewer details in JSON.",
    "trial": false
  },
  "access": { "in": "header", "key": "X-Origin-Key", "value": "your-origin-secret" },
  "endpoints": [{
    "name": "Get Company Reviews",
    "description": "Returns the latest public reviews for a company domain with pagination.",
    "method": "GET",
    "base_url": "https://origin.example.com/v1/items/||domain||",
    "path_params": { "domain": "example.com" },
    "parameters": [
      { "key": "page", "type": "number", "description": "Page number, starting at 1.", "value": "1", "required": false }
    ],
    "headers": [{ "key": "Accept", "value": "application/json" }],
    "example_response": { "reviews": [{ "rating": 5 }] }
  }],
  "plans": [
    { "name": "Basic", "interval": "Monthly", "price": 24.99, "max_requests": 1000 },
    { "name": "Pro", "interval": "Monthly", "price": 49.99, "max_requests": 5000 },
    { "name": "ProPlus", "interval": "Monthly", "price": 99.99, "max_requests": 15000, "rate_limit": 120 }
  ],
  "faqs": [{ "question": "What data does it return?", "answer": "Public reviews with rating and text." }],
  "slaves": [{ "name": "Company Reviews Lookup API" }]
}
```

## Regras

**Identidade.** `product_key` é o seu próprio id estável para o listing. Uma chave nova cria o listing; uma chave que você já usou o atualiza. Uma chave pertence à conta que a criou (`403` para qualquer outra). Listings excluídos não aceitam edições (`409`).

**Publicação.** O listing vai ao ar quando passa pelas [regras de qualidade](https://zylalabs.com/pt/docs/quality-rules) e tem ao menos um endpoint com uma resposta de exemplo e planos ativos. Sem isso, `"publish": true` retorna `422`. Omita `publish` para publicar assim que estiver pronto, ou envie `"publish": false` para mantê-lo como rascunho. `false` nunca despublica um listing que já está no ar.

**Campos da API.** `name` segue as [regras de nome](https://zylalabs.com/pt/docs/quality-rules): até 50 caracteres, inclui a palavra "API", único no hub. `short_description` com no mínimo 50 caracteres. A Zyla completa o resto da página do listing para você: a descrição longa é construída a partir da sua descrição curta, e a categoria e as tags são escolhidas com IA. Se você enviar `long_description`, `category_id`, `tags` ou `website_url`, eles são ignorados e listados em `warnings`.

**Endpoints.** Quando `endpoints` está presente, ele é a lista completa: os endpoints são correspondidos por método + `base_url` (sem a query string), os novos são criados e os que faltam na lista são excluídos. Omita `endpoints` para deixá-los inalterados.
- Descrição com no mínimo 40 caracteres. Método GET, POST, PUT, DELETE ou PATCH.
- `base_url` precisa ser uma URL válida. Parâmetros de caminho vão entre `||`, como em `/items/||domain||`, com um valor de exemplo em `path_params`.
- Parâmetros precisam de `key`, `type` (string, number, email, url, domain, date, datetime) e uma descrição com no mínimo 10 caracteres.
- `example_response` é obrigatório, com até 10.000 caracteres.

**Segredo de origem (`access`).** Um header ou query parameter que a Zyla adiciona a toda chamada à sua origem, para que seu servidor só aceite tráfego do hub. É armazenado de forma oculta e nunca é retornado ou registrado em log. Omita-o para manter o atual; envie `null` para removê-lo.

**Planos.** Nomes exatos: Free, Basic, Pro, ProPlus, Premium, Elite, Ultimate, Pay as you go. `price` em USD; planos anuais levam seu preço anual final. `max_requests` por ciclo; um plano mais barato precisa incluir menos requisições do que um mais caro no mesmo intervalo. `rate_limit` de 60 a 240 por minuto. Pelo menos três planos mensais pagos precisam permanecer ativos. Se você não enviar planos em um listing novo, um conjunto padrão é criado.

**FAQs.** Lista completa quando presente, até 10. Pergunta com 5–100 caracteres, resposta com 3–700.

**APIs vinculadas (`slaves`).** Variantes da sua API com nome e página próprios que reutilizam seus endpoints. São correspondidas por nome e seguem as alterações feitas nos endpoints da API principal. A API principal precisa ter endpoints, e uma API vinculada não pode ter APIs vinculadas próprias.

**Exclusão.** `{"product_key": "...", "delete": true}` exclui o listing. É recusada com `409` enquanto houver assinaturas pagas. APIs vinculadas só são excluídas se você as nomear em `slaves`.

**Não suportado.** Transformações de resposta, corpos de requisição e upload de arquivos (`422 not_supported`). Use o assistente web para isso.

## Respostas

Sucesso: `{"success": true, "listing": {...}, "warnings": []}`, com `201` na criação e `200` na atualização. `listing.url` é definido assim que o listing está no ar.

| Status | `code` | Significado |
|---|---|---|
| 401 | `unauthenticated` | Chave ausente ou inválida |
| 403 | `forbidden` | Conta não verificada ou bloqueada, ou o `product_key` pertence a outra conta |
| 404 | `not_found` | `product_key` desconhecido |
| 409 | `name_taken`, `active_subscriptions`, `endpoints_required`, `listing_deleted`, `slave_of_slave`, `product_key_conflict` | Conflito; nada foi alterado |
| 422 | `validation_failed`, `ai_validation_failed`, `not_supported` | `errors` indexado por campo, por exemplo `endpoints.2.parameters.0.description` |
| 429 | `creation_limit_reached` | Cota de novas APIs esgotada; `retry_after` em segundos e um header `Retry-After` |
| 503 | `ai_unavailable` | A verificação de conteúdo não respondeu; nada foi salvo; tente novamente |
| 500 | `server_error` | Falha inesperada; nada foi salvo |


---
Source: https://zylalabs.com/pt/docs/listings-api
