# Sandbox controls

> Drive a synthetic patient through new records, revoked consent, expiry, and a failed sync on demand.

After `simulate` creates a synthetic patient, you can make things happen to them instead of waiting.

```bash
curl -X POST "https://api.finchnode.com/api/v1/sandbox/subjects/$SUBJECT/events" \
  -H "Authorization: Bearer $FINCHNODE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"type": "records.advance"}'
```

## Pick a control

| `type` | What happens | What you'll see |
| --- | --- | --- |
| `records.advance` | The source imports the scenario's changes now. | Its new and changed records, and deletions if it has any, in the change feed; `records.updated` for continuous shares. |
| `consent.revoke` | The patient revokes every active share. | `consent.revoked`; reads return `410 consent_inactive`. |
| `consent.expire` | Every active share's expiry is set to now. | `consent.expired` within about 15 seconds. |
| `source.fail` | The source's next import fails, and runs now. | `sync.failed` for continuous shares; a warning on the snapshot. |

`consent.revoke` and `consent.expire` answer `applied`. `records.advance` and `source.fail` answer `queued`, and their effect arrives when the import finishes. On a continuous share, wait for `records.updated` or `sync.failed` before you read.

Each scenario has one set of changes. The first `records.advance` applies them; later ones re-import the same records. `source.fail` fails a healthy source once. A `source-unavailable` source that already fails keeps failing.

## Two-source patients

For `multi-source-overlap` and `source-unavailable`, add `source` to target one health system, such as `"source": "quillhaven-medical"`. Leave it out to act on both.

## Limits

- Sandbox keys only. A production key gets `403 sandbox_only`.
- Only patients your application's `simulate` created. Any other subject returns `404 not_found`.
- Behavior scenarios support every control except `records.advance`. Others return `409 control_unsupported`.
- `records.advance` and `source.fail` need a connected source, or they return `409 subject_not_connected`.
