# Testing the API



> Mailrith's public API can be tested manually with local curl requests and automatically through the integration suite. This page shows the repo-native commands for both paths.



- Human page: https://mailrith.com/developers/testing-the-api

- Category: Getting Started

- Reading time: 7 min read



## What this guide covers

Run the local worker, generate a workspace key, exercise the endpoints, and execute automated integration coverage.



## Run the Services Locally

Use the full local stack when you need the app UI, local data, and API worker together. This is the best path when you want to create a workspace key in the UI and then immediately test API requests against the same workspace.

Use the API worker command when you only need the public API surface and already have the local data or fixtures needed for your test.

Local testing is useful before wiring a real external system because it lets you confirm request shape, authentication behavior, pagination, and error handling without touching production data.

1. Start the full stack with `pnpm dev` when you need to create data or keys through the Mailrith UI.
2. Use `pnpm test:e2e:serve:api` when you only need the API worker.
3. Open the local app, create or select a workspace, and create a local workspace API key.
4. Send one unauthenticated request to confirm the API worker is reachable.
5. Send one authenticated request to confirm the key, workspace scope, and request body are correct.
6. Connect the external system or larger sync job only after those checks pass.

**Full Stack**

```bash
pnpm dev
```

**API Worker Only**

```bash
pnpm test:e2e:serve:api
```

## Generate a Workspace API Key

When the app is running locally, open `http://localhost:5173`, use the workspace switcher to choose the target workspace, click `Settings`, open the `API Keys` tab, and generate a key from `Integration Credentials`.

The local API worker listens on `http://localhost:8787`, so the token can be used immediately against the versioned `/v1` surface.

Use a clearly fake or local-only key name, such as `Local API Smoke Test`, so it is easy to identify and remove later. Do not paste production API keys into local test scripts unless you are intentionally testing production behavior.

1. Open `http://localhost:5173` while the local app is running.
2. Switch to the local workspace you want the API request to use.
3. Click `Settings`, open the `API Keys` tab, and click `Generate API Key` in `Integration Credentials`.
4. In the `Generate API Key` drawer, choose the workspace, name the key `Local API Smoke Test` or another clearly local name, choose the access level, choose the expiration, and click `Generate`.
5. Copy the full secret once and store it in your local shell environment.
6. Use that key only against `http://localhost:8787/v1` unless you intentionally created it in production.

## Exercise the Endpoints

Start with unauthenticated metadata endpoints. If those respond, the worker is reachable. Then send a protected request using the workspace key. This separates connection problems from authentication or request-body problems.

For protected requests, test one simple create or list call before building a larger sync. A single subscriber upsert is enough to prove the key, workspace scope, JSON body, and response parsing path.

When a request fails locally, keep the full response body. Mailrith's error envelope includes a stable code that tells you whether the problem is authentication, validation, missing resource, conflict, or another expected API condition.

1. Call `GET /v1` first. If it fails, fix the worker URL before debugging authentication.
2. Call `GET /v1/openapi.json` next. If it succeeds, your tool can read the current contract.
3. Call `GET /v1/capabilities` with the workspace key. If it fails with `401`, fix the key.
4. Send a single `POST /v1/subscribers` request with a test email.
5. If the request succeeds, verify the subscriber in the app.
6. If the request fails, inspect the error code and follow [Errors](https://mailrith.com/developers/errors.md) instead of retrying blindly.

**Unauthenticated Checks**

```bash
curl http://localhost:8787/v1
curl http://localhost:8787/v1/openapi.json
```

**Protected Request**

```bash
curl -X POST http://localhost:8787/v1/subscribers \
  -H "Authorization: Bearer mrk_example_secret_key" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "ada@example.com",
    "name": "Ada Lovelace",
    "new_tags": ["Website Signup"]
  }'
```

## Run the Automated Coverage

Use automated coverage when you change the public contract, API worker behavior, authentication rules, request validation, SDK generation, or docs that depend on the contract.

The integration tests boot the worker against a test database and verify authentication, list flows, create and update flows, webhook subscriptions, and async import and export jobs.

If the tests fail after a docs-only change, inspect whether the docs imported a value incorrectly or whether the generated OpenAPI contract changed unexpectedly.

- `tests/integration/public-api-v1.test.ts` covers the versioned public endpoints.
- `tests/integration/workspace-api-keys.test.ts` covers key creation and verification.

**Integration Tests**

```bash
pnpm exec vitest run --config vitest.integration.config.ts tests/integration/public-api-v1.test.ts tests/integration/workspace-api-keys.test.ts
```



## Related Guides

- [Quickstart](https://mailrith.com/developers/quickstart.md): Start with one workspace API key, one authenticated request, and the generated response envelope. This page covers the minimum needed to go from zero to a working subscriber sync.

- [Authentication](https://mailrith.com/developers/authentication.md): Every protected `v1` request resolves through a workspace-scoped API key. This page covers the header shape, workspace scoping behavior, and authentication failure handling.

- [API Reference](https://mailrith.com/developers/api-reference.md): The full API reference is generated from the same public contract used by the API worker and SDK tooling. Use it for exact paths, methods, parameters, request schemas, response schemas, operation IDs, and the downloadable OpenAPI document.
