# Testing

Source: https://modulify.ai/docs/api/testing

Try the API safely, check a token, import every method into Postman, and trace a call with its request id.

Every call runs against your real account, so test with care. A few habits make that safe.

## Start with a read-only token

When you try the API for the first time, create a token that can only read. On the Tokens page, untick every scope whose label starts with something other than "Read", which leaves the token unable to change, send or delete anything. A call to a method that writes then comes back as a `403` naming the scope it needs, which is a useful check in itself.

Good first calls with such a token:

| Method | What you learn |
| --- | --- |
| `list_workspaces` | The workspace ids, and that the token works |
| `list_sites` | The site ids in one workspace |
| `get_site` | Everything about one site |
| `get_publish_status` | Whether a site is live, and at which addresses |
| `list_messages` | What the site agent has already been asked |

When you move on to writing, point the script at a test site first.

## Check the token

`GET /v1/token` shows what the token is and what it can reach, and runs nothing:

```bash
curl https://api.modulify.ai/v1/token \
  -H "Authorization: Bearer YOUR_TOKEN"
```

`GET /v1/tools` lists every method the token's scopes allow, with the arguments each one takes:

```bash
curl https://api.modulify.ai/v1/tools \
  -H "Authorization: Bearer YOUR_TOKEN"
```

Neither counts against the token's per-minute budget.

## Use Postman or Insomnia

`https://api.modulify.ai/v1/openapi.json` describes every method in OpenAPI 3.1 and needs no token to read.

### Import the description

In Postman choose **Import** and paste the address. In Insomnia, create a document from the same address. Every method arrives as a request, grouped by area, with its arguments.

### Set the token once

Set the collection's authorization to **Bearer Token** and paste your token, so every request carries it.

### Send a request

Open a method, fill in its body and send it. The body is a JSON object, and an empty body means no arguments.

See [OpenAPI](https://modulify.ai/docs/api/openapi) for what the description contains.

## Read the request id

Every call that reaches a method answers with an `X-Request-Id` header. It names that one call in Modulify's records, so quote it when you ask for help with a call that did something unexpected.

```bash
curl -i -X POST https://api.modulify.ai/v1/list_workspaces \
  -H "Authorization: Bearer YOUR_TOKEN"
```

`-i` prints the headers. Next to the request id you will see `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset`, which show how much of this minute's budget is left. See [Rate limits](https://modulify.ai/docs/api/rate-limits).

## Retry safely while testing

A test script that fails half way and runs again can repeat a write. Send an `Idempotency-Key` header with every write, so a repeat of a call that already succeeded gets the first answer back instead of running a second time. See [Idempotency and retries](https://modulify.ai/docs/api/idempotency).

## Next

- [Errors](https://modulify.ai/docs/api/errors) when a call does not do what you expected.
- [Security](https://modulify.ai/docs/api/security) before a token leaves your machine.