> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pinakelai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Testing your integration

> Test keys, registers that suit tests, contract tests against the OpenAPI document, and how to exercise error handling.

## Use a test key

A `pk_test_` key returns the same data as a live key, has lower rate limits, and is not billed. Use it for development, CI and the playground on this site. Keep live keys for production.

There is no separate sandbox: test keys read the real, current registers. Write tests that hold however the data changes.

## Pick small registers

The Andorran (`AD`) and Albanian (`AL`) registers are small, so searches over them are fast and their results are easy to check by hand. They are a good default scope for integration tests:

```bash theme={null}
curl -G "https://api.pinakelai.com/v1/trademarks" \
  -H "Authorization: Bearer $PINAKEL_TEST_KEY" \
  --data-urlencode "jurisdiction=AD" \
  --data-urlencode "number=48000"
```

Assert on structure and on facts that do not drift: that the record `tm_AD_2376e41e-3d24-57e3-af6f-6a176f9985ba` exists and has registration number `48000`, not that a search returns exactly 17 records.

## Contract tests

[`/v1/openapi.json`](https://api.pinakelai.com/v1/openapi.json) is the machine-readable contract: OpenAPI 3.1, with every parameter, response and error. Validate the responses your code depends on against it, for example with [Schemathesis](https://schemathesis.readthedocs.io) or an OpenAPI validator in your test framework. Allow additional properties and unknown enumeration values, as v1 adds them over time (see [Versioning](https://docs.pinakelai.com/guides/versioning.md)).

## Exercise your error handling

You can produce most errors deliberately with a test key:

| Error | Request |
| - | - |
| 400 `invalid-request`, `unknown-parameter` | `GET /v1/trademarks?jurisdiction=AD&colour=red` |
| 400 `invalid-request`, `missing-filter` | `GET /v1/trademarks` |
| 400 `invalid-request`, `reserved-parameter` | `GET /v1/trademarks?q=noky` |
| 400 `invalid-cursor` | `GET /v1/trademarks?jurisdiction=AD&cursor=not-a-cursor` |
| 400 `cursor-mismatch` | A valid search cursor sent with different filters |
| 404 `not-found` | `GET /v1/trademarks/tm_AD_no-such-record` |
| 404 `unknown-endpoint` | `GET /v1/marks` |
| 405 `method-not-allowed` | `DELETE /v1/trademarks/tm_AD_2376e41e-3d24-57e3-af6f-6a176f9985ba` |
| 415 `unsupported-media-type` | `POST /v1/trademarks/batch` with `Content-Type: text/plain` |
| 413 `payload-too-large` | `POST /v1/trademarks/batch` with a body over 64 KB |
| 422 `query-too-broad` | `GET /v1/trademarks?mark_text_phrase=科技` |

Do not test authentication failures or rate limits against the live API in a loop. Twenty lookups of unknown keys within a minute block your IP address for five minutes, and deliberately exhausting a rate limit slows your other tests. Simulate 401, 429 and 503 responses with a mock instead, using the bodies and headers shown in the [errors reference](https://docs.pinakelai.com/api-reference/errors.md).

## Smoke checks

[`GET /v1/health`](https://docs.pinakelai.com/api-reference/account/health) needs no key and is not counted. It returns 200 when the API can reach its data stores, and 503 otherwise. Use it in deployment smoke checks and status pages, not as a reason to stop your own service: a 503 there means requests may fail for a while, and your error handling covers that.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.