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

# Test mode

> Build and test every path of your integration without touching CAC.

Test mode is a full copy of the API that never reaches CAC and never moves money. Use a test key
(`fc_test_…`) and every endpoint works exactly as in live mode, with the same requests, responses,
statuses and webhooks.

What test mode can't know is what CAC would decide. So you choose: add a `simulate` query
parameter and the registration takes that path. Live keys ignore `simulate`, so you can leave it in
code paths you share between modes (though you'll usually only send it from tests).

> [!NOTE]
>
> The only difference you'll see when you switch to a live key is that `simulate` stops having an
> effect, because real outcomes now come from CAC.

## Name checks

Without `simulate`, test mode applies CAC's naming rules (no single-word names, no restricted
words, a qualifier such as VENTURES at the end) and otherwise says the name is available. It never
searches the real registry. To get any other answer, pass `simulate`:

```bash theme={null}
curl "https://api.fastcac.com/v1/name-checks?simulate=name_exists" \
  -H "Authorization: Bearer $FASTCAC_KEY" -H "Content-Type: application/json" \
  -d '{"name": "Ada Foods Ventures", "line_of_business": "Educational Services And Consultancy"}'
```

```json Response theme={null}
{
  "object": "name_check",
  "name": "ADA FOODS VENTURES",
  "line_of_business": "Educational Services And Consultancy",
  "available": false,
  "requires_certificate": false,
  "reason": {
    "code": "name_exists",
    "message": "A business with this name is already registered with CAC.",
    "accepted_qualifiers": null,
    "words": null,
    "conflicting_name": "ADA FOODS VENTURES"
  },
  "similarity_score": 100.0,
  "most_similar_name": "ADA FOODS VENTURES",
  "similar_names": [
    "ADA FOODS VENTURES"
  ],
  "suggested_names": [
    "ADA FOODS CONCEPTS",
    "ADA FOODS HUB"
  ]
}
```

| `simulate` | Result |
| - | - |
| `available` | Available. |
| `requires_certificate` | Available, with `requires_certificate: true`. |
| Any [reason code](https://docs.fastcac.com/guides/name-checks.md#reason-codes) | Not available, with that reason, e.g. `name_exists`, `name_too_similar`, `restricted_word`, `qualifier_missing`. |

## Documents

`POST /v1/registrations/{id}/documents?simulate=rejected` makes the upload come back
`rejected`, with a `reason`, and fires `document.rejected`. Without it, uploads are `verified`.

## What happens after submit

Pass `simulate` (and `simulate_query`) when you submit. They decide what happens after payment.

| `simulate` | After payment |
| - | - |
| `approved` (default) | `submitted`, then `approved` about 60 seconds later. |
| `verification_failed` | The identity check fails on `proprietors[0].nin`. Fix it and submit again. |
| `queried` | `submitted`, then `queried` about 60 seconds later, with the items in `simulate_query`. |
| `rejected` | `submitted`, then `rejected` about 60 seconds later. |

`simulate_query` is a comma-separated list of what CAC asks about. Each item uses CAC's own wording:

| `simulate_query` | Queried field | `code` |
| - | - | - |
| `name_exists` | `proposed_names` | `name_exists` |
| `qualifier_missing` | `proposed_names` | `qualifier_missing` |
| `single_word` | `proposed_names` | `single_word` |
| `offensive_language` | `proposed_names` | `offensive_language` |
| `fraudulent_association` | `proposed_names` | `fraudulent_association` |
| `passport_unclear` (default) | `proprietors[0].documents.passport` | `document_unclear` |
| `means_of_id_unclear` | `proprietors[0].documents.means_of_id` | `document_unclear` |
| `first_name_mismatch` | `proprietors[0].first_name` | `name_mismatch` |
| `last_name_mismatch` | `proprietors[0].last_name` | `name_mismatch` |
| `line_of_business_unclear` | `line_of_business` | `other` |

```bash theme={null}
curl -X POST "https://api.fastcac.com/v1/registrations/$REG_ID/submit?simulate=queried&simulate_query=qualifier_missing,passport_unclear" \
  -H "Authorization: Bearer $FASTCAC_KEY"
```

A registration that's resubmitted after a query is then approved.

## Skipping the wait

Test helpers move a registration on immediately. They exist only in test mode.

```bash theme={null}
curl https://api.fastcac.com/v1/test/registrations/$REG_ID/advance \
  -H "Authorization: Bearer $FASTCAC_KEY" -H "Content-Type: application/json" \
  -d '{"to": "approved"}'
```

| From | `to` |
| - | - |
| `pending_payment` | `paid` (also runs the identity check, so you get `submitted` or `verification_failed`) |
| `paid` | `submitted` |
| `submitted` | `approved`, `queried` or `rejected` |

Anything else is `409 invalid_state`. Answering a query is never a shortcut: fix the fields and
submit, as in live mode ([Handling CAC queries](https://docs.fastcac.com/guides/queries.md)). The **Simulate** menu on a
registration in the dashboard does the same as `advance`.

## Test data

Test mode checks values exactly as live mode does: real-looking NINs (11 digits), Nigerian
postcodes (6 digits), adult proprietors, a `line_of_business` from the list. Use made-up people;
test-mode data is never sent anywhere.


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