# New Endpoint Checklist

Every time a new API endpoint is added or an existing one is updated, the files below must be checked.
Use the **stage branch** of `dashboard-api` as the source of truth for schemas, field names, enums, and credit costs.

## 1. `openapi.yaml` — endpoint definition + schemas

### 1a. Path entry (under `paths:`)

Place the new path in the correct position relative to existing endpoints. The order within a tag group in `x-tagGroups` controls sidebar order.

Required fields inside the method block:

| Field | Notes |
|  --- | --- |
| `operationId` | Convention: `public_v1_{path_segments}_{method}` (e.g. `public_v1_creators_audience_overlap_create` for POST, `public_v1_enrichment_batch_retrieve` for GET). |
| `description` | Single-quoted YAML string with markdown. Required sections: **What you get** and **Credits**. Additional sections (e.g. **When to use**, **Result format**, **How it works**) are optional. Must end with the `<div class="ic-ai-prompt-root" data-endpoint="..."></div>` placeholder. See `OPENAPI_GUIDE.md` for the full template. |
| `summary` | Human-readable name. **Must match the tag name exactly** — it becomes the sidebar label. |
| `tags` | Array with one item — the tag name. Multiple endpoints can share one tag (e.g. all batch endpoints share `Batch enrichment`). |
| `requestBody` | **POST with JSON body**: include all three content types (`application/json`, `application/x-www-form-urlencoded`, `multipart/form-data`) pointing to the same `$ref`. **POST with file upload** (like batch): use only `multipart/form-data`. **GET endpoints**: use `parameters:` instead (see 1e below). |
| `security` | `- Bearer: []` |
| `responses` | At minimum: `'200'` with the response schema `$ref`. Optionally add `'400'`, `'403'`, `'429'` error responses if the endpoint has documented error cases. |
| `x-credits` | Plain-text string describing the credit cost. |


### 1b. Request + response schemas (under `components/schemas`)

Copy field names, types, enums, `required` lists, and `nullable` flags **exactly** from the backend serializer. Do not rename fields. Do not invent constraints. See `OPENAPI_GUIDE.md` for the Django-to-OpenAPI type mapping.

**Identifier fields** (`handle`, `creators`, `email`, `post_id`, etc.) must always have a `description` explaining what values are accepted (username, profile URL, channel ID, etc.). Check the backend view to see how the value is processed.

### 1c. `tags:` section (near end of file, before `x-tagGroups`)

Add a `- name: Your Tag Name` entry. Optionally add a `description:` if the tag needs explanation. **Both** the `tags:` list and `x-tagGroups` must include the tag.

### 1d. `x-tagGroups:` section (bottom of file)

Add the new tag to the correct group. **If you skip this, the endpoint will not appear in the sidebar.**

### 1e. GET endpoints with path/query parameters

GET endpoints use `parameters:` instead of `requestBody:`:


```yaml
      parameters:
      - in: path           # or "query" for query params
        name: batch_id
        schema:
          type: string
        required: true
        description: The batch job identifier
```

## 2. `scripts/copy-for-ai.js` — AI prompt builder card

### 2a. `ENDPOINTS` array (starts at line ~210)

Insert a new entry in the same order as the sidebar. Required fields:


```js
{
  key: "kebab-case-id",          // must match data-endpoint attribute in openapi.yaml
  name: "Human-Readable Name",
  method: "POST",                // or "GET"
  path: "/public/v1/...",        // include trailing slash
  desc: "One-sentence description.",
  strategy: "Explain in plain English how to use this endpoint to [verb specific to endpoint]. Walk me through [specific guidance]. No code needed — just a clear, actionable plan.",
  required: [
    'field (type): description'
  ],
  credits: "X credits per ...",
  example: '{ ... }'            // realistic sample JSON response
}
```

Optional fields:

| Field | When to include |
|  --- | --- |
| `type: "platform"` | Only if the endpoint uses platform-specific discovery filters (currently only `discovery` and `similar`). When set, the prompt builder shows a platform dropdown that injects the platform-specific filter list from the `FILTERS` object. |
| `optional: [...]` | Array of `{ name, label, prompt, checked }` objects. Include when the endpoint has optional parameters the user might want to toggle on/off in the prompt. `checked: true` means the toggle is on by default. |


### 2b. `PAGINATED` object (line ~461)

Add the key **only** if the endpoint uses page-number pagination (currently only `discovery` and `similar`). This causes the generated prompt to include a pagination loop instruction. Cursor-based pagination endpoints (like `creator-posts`) do **not** go here — they handle pagination differently.

### 2c. `BATCH_KEYS` object (line ~462)

Add the key **only** if the endpoint is part of the batch enrichment workflow. This causes the generated prompt to include batch polling/download instructions.

### 2d. `data-endpoint` div in openapi.yaml

The endpoint's `description` in openapi.yaml must end with:


```html
<div class="ic-ai-prompt-root" data-endpoint="kebab-case-id"></div>
```

The `data-endpoint` value must match the `key` in the `ENDPOINTS` array exactly. If they don't match, the prompt builder card won't render on that endpoint page.

## 3. `scripts/credit-calculator.js` — credit calculator widget

### 3a. `RATES` object (line 2)

Add an entry:


```js
your_key: { label: "Display Name", unit: "request", rate: 0.5 },
```

The `unit` value determines the hint text below the quantity input:

| `unit` value | Hint text shown |
|  --- | --- |
| `"creator returned"` | "Number of creators returned" |
| `"request"` | "Number of requests" |
| `"record"` | "Number of successfully enriched records" |


The `rate` and `unit` come from the backend view's `@public_api_wrapper` decorator:


```python
@public_api_wrapper(endpoint_name="get_verified_connected_socials", min_credits_cost=0.5)
```

- `rate` = the `min_credits_cost` value.
- `unit` = `"creator returned"` for discovery-style endpoints, `"request"` for flat-rate endpoints, `"record"` for enrichment endpoints.


### 3b. `guides/usage-limits.md` — HTML `<option>` element

Add a new `<option>` inside the `<select id="cc-endpoint">` element:


```html
<option value="your_key">Display Name</option>
```

The `value` must match the key in the `RATES` object. The display text must match the `label`.

**Important**: Every key in `RATES` must have a corresponding `<option>` in the HTML, and vice versa. If they're out of sync, the calculator will either show an endpoint it can't calculate or silently skip one.

## 4. `@theme/styles.css` — anchor ID hiding

Add the new endpoint's anchor ID to the CSS selector block (line ~378):


```css
#discovery-api,
#similar-creators,
#your-new-endpoint-id,   /* <-- add here */
...
#faq {
  height: 20px !important;
  opacity: 0 !important;
}
```

The anchor ID is the kebab-case version of the tag name (e.g. tag `"Audience Overlap"` becomes `#audience-overlap`). Redocly generates these anchors automatically from the tag name.

## 5. `redocly.yaml` — framework config

This file **does not** need per-endpoint changes. However, if you add a new JavaScript file (not just an endpoint), you must register it under `scripts.body`:


```yaml
scripts:
  body:
    - src: ./scripts/credit-calculator.js
      defer: true
    - src: ./scripts/copy-for-ai.js
      defer: true
    - src: ./scripts/your-new-script.js    # <-- add here if needed
      defer: true
```

## 6. Files that do NOT need updating

| File | Why |
|  --- | --- |
| `sidebars.yaml` | Controls only top-level navigation pages (Getting Started, Core Concepts, etc.). The API endpoint sidebar is auto-generated from `openapi.yaml` tags and `x-tagGroups`. |
| `index.md` | Landing page — does not list individual endpoints. |


## 7. Updating an existing endpoint

When an existing endpoint changes (new fields, removed fields, credit cost change, etc.):

| What changed | Files to update |
|  --- | --- |
| Schema fields added/removed/renamed | `openapi.yaml` (path description + component schema), `copy-for-ai.js` (required/optional arrays, example JSON) |
| Credit cost changed | `openapi.yaml` (`x-credits`), `credit-calculator.js` (`RATES` rate value), `copy-for-ai.js` (credits string) |
| New optional parameter | `openapi.yaml` (schema), `copy-for-ai.js` (optional array) |
| Endpoint renamed/moved | All files in this checklist |
| Endpoint deprecated | Add `deprecated: true` to the method block in `openapi.yaml`. Keep it in all other files until fully removed. |


## 8. Verification

After making all changes:

1. **Lint**: `npx @redocly/cli lint openapi.yaml` — fix any new errors (ignore pre-existing warnings).
2. **Preview**: `npx @redocly/cli preview` — then check:
  - Endpoint appears in the sidebar under the correct group.
  - Endpoint page renders with all description sections.
  - Request/response schemas render with correct field names and types.
  - AI prompt builder card appears at the bottom of the endpoint page.
  - Clicking "Copy prompt" generates a valid prompt with correct fields.
  - Credit calculator dropdown includes the new endpoint.
  - Selecting it and entering a quantity shows the correct credit calculation.
3. **Cross-check against backend**: Compare every schema field name, type, enum value, and nullability against the stage branch serializer. They must match exactly.
4. **Sync check**: Confirm that every `data-endpoint` in openapi.yaml has a matching `key` in `copy-for-ai.js`, and every key in `RATES` has an `<option>` in `usage-limits.md`.