# Simulations

Generate test enrolment states, test alerts, and test scheme notices for TEST mode organisations.

**Base URL:** `https://api.chargebackstop.com/v1/simulate/`

**Authentication:** Bearer token via API key.

Required abilities:

* `simulations:enrollments` for `PATCH /v1/simulate/enrolments/{enrolment_id}`
* `simulations:alerts` for `POST /v1/simulate/alerts`
* `simulations:lookups` for `POST /v1/simulate/lookups`
* `simulations:scheme_notices` for `POST /v1/simulate/scheme-notices`

**Access scope model:**

* Organisation-level keys can simulate data for their own organisation only.
* Admin partner-group keys can simulate data across all organisations for their partner.
* Non-admin partner-group keys can simulate data only for organisations assigned to their group.

Typical simulation flow:

{% stepper %}
{% step %}
**Create an enrolment**

Create an enrolment with `/v2/enrolments`.
{% endstep %}

{% step %}
**Enable the enrolment for simulation**

Set that enrolment to `ENABLED` with:

`PATCH /v1/simulate/enrolments/{enrolment_id}`
{% endstep %}

{% step %}
**Generate a simulated alert**

Generate a simulated alert with `POST /v1/simulate/alerts`.
{% endstep %}

{% step %}
**Generate a simulated lookup**

Generate a simulated lookup with `POST /v1/simulate/lookups`.
{% endstep %}

{% step %}
**Generate a simulated scheme notice**

Generate a simulated scheme notice with `POST /v1/simulate/scheme-notices`.
{% endstep %}
{% endstepper %}

***

## PATCH /v1/simulate/enrolments/{enrolment\_id} - update enrolment simulation status

Updates an enrolment status for simulation use.

**API level:** Organisation-level and partner-level\
**Authentication:** `simulations:enrollments`

### URL parameters

| Parameter      | Type   | Description            |
| -------------- | ------ | ---------------------- |
| `enrolment_id` | string | Enrolment ID to update |

### Request body

| Field    | Type   | Required | Description                                     |
| -------- | ------ | -------- | ----------------------------------------------- |
| `status` | string | Yes      | New enrolment status: `ENABLED` or `UNENROLLED` |

### Important behaviour

* This endpoint is only available for TEST mode organisations.
* The enrolment must be accessible to the authenticated API key.
* For `ETHOCA_ALERT` enrolments, setting `status` to `ENABLED` activates configured descriptors for simulation matching.

### Example 1 request

```bash
curl -X PATCH "https://api.chargebackstop.com/v1/simulate/enrolments/enrl_abc456" \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "ENABLED"
  }'
```

### Example 1 response

```json
{
  "id": "enrl_abc456",
  "organisation_id": "org_test123",
  "merchant_ids": ["mrch_abc123"],
  "type": "ETHOCA_ALERT",
  "status": "ENABLED",
  "ethoca_alert": {
    "descriptors": [
      {
        "descriptor": "TESTMERCHANT.COM",
        "match_type": "EXACT_MATCH"
      }
    ]
  },
  "verifi_rdr": null,
  "created_at": "2026-02-10T12:00:00Z",
  "updated_at": "2026-02-16T08:15:00Z",
  "note": null,
  "links": [
    {
      "rel": "self",
      "uri": "/v2/enrolments/enrl_abc456"
    }
  ]
}
```

***

## POST /v1/simulate/alerts - create simulated alert

Creates a simulated network alert.

**API level:** Organisation-level and partner-level\
**Authentication:** `simulations:alerts`

### Request body

| Field                                   | Type    | Required | Description                                                                                               |
| --------------------------------------- | ------- | -------- | --------------------------------------------------------------------------------------------------------- |
| `organisation_id`                       | string  | Yes      | Organisation ID. Must be in TEST mode and accessible to the key                                           |
| `enrolment_id`                          | string  | Yes      | Enrolment ID that belongs to `organisation_id` and is an alert enrolment (`ETHOCA_ALERT` or `VERIFI_RDR`) |
| `status`                                | string  | No       | Alert status: `ACTION_REQUIRED`, `RESOLVED`, `INVALID`. Verifi RDR only supports `RESOLVED` or `INVALID`  |
| `transaction_refund_outcome`            | string  | No       | Refund outcome: `REFUNDED` or `NOT_REFUNDED`. Only valid with `status=RESOLVED`                           |
| `card_scheme`                           | string  | No       | Card scheme. Use any supported scheme value, for example `VISA`, `MASTERCARD`, `AMEX`                     |
| `amount_in_cents`                       | integer | No       | Transaction amount in cents. Must be a positive integer                                                   |
| `currency_code`                         | string  | No       | ISO 4217 currency code, for example `USD`, `EUR`, `GBP`                                                   |
| `transaction_acquirer_reference_number` | string  | No       | ARN. Must be exactly 23 characters                                                                        |
| `transaction_authorisation_code`        | string  | No       | Authorisation code. Must be exactly 6 characters                                                          |

### Important behaviour

* This endpoint is only available for TEST mode organisations.
* The enrolment must be an alert enrolment: `ETHOCA_ALERT` or `VERIFI_RDR`.
* If `status` is omitted, the simulator chooses a valid status.
* If `transaction_refund_outcome` is provided without `status`, the created alert is set to `RESOLVED`.
* Simulated alerts trigger the same `alert.created` event flow as non-simulated alerts.

### Example 2 request

```bash
curl -X POST "https://api.chargebackstop.com/v1/simulate/alerts" \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "organisation_id": "org_test123",
    "enrolment_id": "enrl_abc456",
    "status": "RESOLVED",
    "transaction_refund_outcome": "REFUNDED",
    "card_scheme": "VISA",
    "amount_in_cents": 5000,
    "currency_code": "USD"
  }'
```

### Example 2 response

```json
{
  "id": "netalrt_xyz789",
  "alert_network_id": "SIM123456",
  "organisation_id": "org_test123",
  "merchant_id": "mrch_abc123",
  "enrolment_id": "enrl_abc456",
  "enrolment_type": "ETHOCA_ALERT",
  "status": "RESOLVED",
  "chargeback_reason_code": null,
  "transaction_amount_in_cents": 5000,
  "transaction_currency_code": "USD",
  "transaction_authorised_at": "2026-02-10T10:30:00Z",
  "action_required_deadline": null,
  "transaction_authorisation_code": "ABC123",
  "transaction_acquirer_reference_number": "12345678901234567890123",
  "transaction_statement_descriptor": "TESTMERCHANT.COM",
  "transaction_card_bin": "400000",
  "transaction_card_last4": "1234",
  "transaction_card_scheme": "VISA",
  "transaction_card_issuer": "Bank of America",
  "transaction_refund_outcome": "REFUNDED",
  "transaction_network_id": null,
  "subscription_cancel_outcome": null,
  "note": null,
  "created_at": "2026-02-16T08:20:00Z",
  "updated_at": "2026-02-16T08:20:00Z",
  "integration_id": null,
  "integration_transaction_id": null
}
```

***

## POST /v1/simulate/lookups - create simulated lookup

Creates a simulated lookup.

**API level:** Organisation-level and partner-level\
**Authentication:** `simulations:lookups`

### Request body

| Field                                   | Type    | Required | Description                                                                                                                     |
| --------------------------------------- | ------- | -------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `organisation_id`                       | string  | Yes      | Organisation ID. Must be in TEST mode and accessible to the key                                                                 |
| `enrollment_id`                         | string  | Yes      | Enrollment ID that belongs to `organisation_id` and is a lookup enrolment (`ETHOCA_CONSUMER_CLARITY` or `VERIFI_ORDER_INSIGHT`) |
| `type`                                  | string  | Yes      | Lookup type: `ETHOCA_CONSUMER_CLARITY`, `ETHOCA_FIRST_PARTY_TRUST`, `VERIFI_ORDER_INSIGHT`, `VERIFI_COMPELLING_EVIDENCE_3`      |
| `parent_lookup_id`                      | string  | No       | Existing lookup ID in the same organisation                                                                                     |
| `lookup_status`                         | string  | No       | Lookup status: `PENDING`, `SUCCEEDED`, `FAILED`, `TIMEOUT`                                                                      |
| `deflection_status`                     | string  | No       | Deflection status: `NOT_ATTEMPTED`, `PENDING`, `SUCCEEDED`, `FAILED`                                                            |
| `card_scheme`                           | string  | No       | Card scheme. Use any supported scheme value, for example `VISA`, `MASTERCARD`, `AMEX`                                           |
| `amount_in_cents`                       | integer | No       | Transaction amount in cents. Must be a positive integer                                                                         |
| `currency_code`                         | string  | No       | ISO 4217 currency code, for example `USD`, `EUR`, `GBP`                                                                         |
| `transaction_acquirer_reference_number` | string  | No       | ARN. Must be exactly 23 characters                                                                                              |
| `transaction_authorisation_code`        | string  | No       | Authorisation code. Must be exactly 6 characters                                                                                |

### Important behaviour

* This endpoint is only available for TEST mode organisations.
* The enrollment must be a lookup enrolment: `ETHOCA_CONSUMER_CLARITY` or `VERIFI_ORDER_INSIGHT`.
* If `lookup_status` is omitted, the simulator uses `SUCCEEDED`.
* If `deflection_status` is omitted, the simulator uses `NOT_ATTEMPTED`.
* The simulator also stores a standard response summary on the lookup record for downstream UI and internal testing use.
* Simulated lookups trigger the same `lookup.created` event flow as non-simulated lookups.
* Simulated lookups do not create billing events or request-response records.

### Example 4 request

```bash
curl -X POST "https://api.chargebackstop.com/v1/simulate/lookups" \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "organisation_id": "org_test123",
    "enrollment_id": "enrl_abc456",
    "type": "ETHOCA_CONSUMER_CLARITY",
    "lookup_status": "SUCCEEDED",
    "deflection_status": "NOT_ATTEMPTED",
    "card_scheme": "VISA",
    "amount_in_cents": 5000,
    "currency_code": "USD",
    "transaction_acquirer_reference_number": "12345678901234567890123",
    "transaction_authorisation_code": "ABC123"
  }'
```

### Example 4 response

```json
{
  "id": "lkup_xyz789",
  "organisation_id": "org_test123",
  "enrollment_id": "enrl_abc456",
  "type": "ETHOCA_CONSUMER_CLARITY",
  "parent_lookup_id": null,
  "lookup_status": "SUCCEEDED",
  "deflection_status": "NOT_ATTEMPTED",
  "transaction_card_bin": "411111",
  "transaction_card_last4": "1234",
  "transaction_arn": "12345678901234567890123",
  "transaction_auth_code": "ABC123",
  "transaction_amount": 5000,
  "transaction_currency": "USD",
  "transaction_date": "2026-02-16T08:20:00Z",
  "transaction_statement_descriptor": "ETHOCA TEST LOOKUP",
  "transaction_network_id": null,
  "integration_id": null,
  "integration_transaction_id": null,
  "created_at": "2026-02-16T08:20:00Z",
  "updated_at": "2026-02-16T08:20:00Z"
}
```

***

## POST /v1/simulate/scheme-notices - create simulated scheme notice

Creates a simulated scheme notice.

**API level:** Organisation-level and partner-level\
**Authentication:** `simulations:scheme_notices`

### Request body

| Field                         | Type     | Required | Description                                                     |
| ----------------------------- | -------- | -------- | --------------------------------------------------------------- |
| `organisation_id`             | string   | Yes      | Organisation ID. Must be in TEST mode and accessible to the key |
| `scheme_notice_type`          | string   | No       | Scheme notice type: `TC15`, `TC40`, or `SAFE`                   |
| `transaction_amount_in_cents` | integer  | No       | Transaction amount in cents. Must be a positive integer         |
| `transaction_currency_code`   | string   | No       | ISO 4217 currency code, for example `USD`, `EUR`, `GBP`         |
| `reported_at`                 | datetime | No       | Reported timestamp in ISO 8601 format                           |

### Important behaviour

* This endpoint is only available for TEST mode organisations.
* If `scheme_notice_type` is omitted, the simulator chooses a valid notice type.
* `TC15` simulations use Verifi dispute-notice semantics: `notice_type=DISPUTE_NOTICE`, `scheme=VISA`.
* Simulated scheme notices trigger the same `scheme_notice.created` event flow as non-simulated scheme notices.
* The response uses the standard public scheme-notice payload, including `fraud_reported_at`.

### Example 3 request

```bash
curl -X POST "https://api.chargebackstop.com/v1/simulate/scheme-notices" \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "organisation_id": "org_test123",
    "scheme_notice_type": "TC15",
    "transaction_amount_in_cents": 5000,
    "transaction_currency_code": "USD",
    "reported_at": "2026-02-16T08:20:00Z"
  }'
```

### Example 3 response

```json
{
  "id": "schntc_xyz789",
  "organisation_id": "org_test123",
  "merchant_id": null,
  "scheme_notice_type": "TC15",
  "notice_type": "DISPUTE_NOTICE",
  "scheme": "VISA",
  "is_revoked": false,
  "notice_revoked_at": null,
  "fraud_reported_at": "2026-02-16T08:20:00Z",
  "transaction_amount_in_cents": 5000,
  "transaction_currency_code": "USD",
  "transaction_card_bin": "411111",
  "transaction_card_last4": "1111",
  "transaction_merchant_name": "ECOM-STUFF.COM",
  "transaction_merchant_id": "003500935000093",
  "transaction_acquirer_reference_number": "12345678901234567890123",
  "transaction_authorisation_code": "ABC123",
  "transaction_original_date": "2026-02-01T08:20:00Z",
  "transaction_purchase_date": null,
  "fraud_type": null,
  "fraud_dispute_eligible": null,
  "created_at": "2026-02-16T08:20:00Z",
  "updated_at": "2026-02-16T08:20:00Z"
}
```

***

## Common error responses

Error responses use this shape:

```json
{
  "errors": [
    {
      "code": "ERROR_CODE",
      "message": "Human-readable message"
    }
  ]
}
```

### Example 4: 401 Unauthorised

```json
{
  "errors": [
    {
      "code": "UNAUTHORISED",
      "message": "Unauthorised"
    }
  ]
}
```

### Example 5: 403 Forbidden

```json
{
  "errors": [
    {
      "code": "FORBIDDEN",
      "message": "Forbidden"
    }
  ]
}
```

### Example 6: 404 Not found

```json
{
  "errors": [
    {
      "code": "NOT_FOUND",
      "message": "Not found"
    }
  ]
}
```

### Example 7: 422 Unprocessable Entity (simulation not allowed)

```json
{
  "errors": [
    {
      "code": "SIMULATION_NOT_ALLOWED",
      "message": "Alert simulation is only allowed for TEST mode organisations. Production Org is in LIVE mode."
    }
  ]
}
```

### Example 8: 422 Unprocessable Entity (simulation validation error)

```json
{
  "errors": [
    {
      "code": "SIMULATION_VALIDATION_ERROR",
      "message": "Invalid currency_code 'INVALID'. Must be a valid ISO 4217 code."
    }
  ]
}
```

### Example 9: 422 Unprocessable Entity (scheme notice validation error)

```json
{
  "errors": [
    {
      "code": "SIMULATION_VALIDATION_ERROR",
      "message": "Invalid scheme_notice_type 'INVALID'. Must be TC15, TC40, or SAFE."
    }
  ]
}
```

### Example 10: 422 Unprocessable Entity (invalid enum value)

```json
{
  "errors": [
    {
      "code": "VALIDATION_ENUM",
      "message": "Validation error at ('body', 'data', 'status'). Input should be 'ENABLED' or 'UNENROLLED'."
    }
  ]
}
```

### Additional reference: 500 Server error

```json
{
  "errors": [
    {
      "code": "SERVER_ERROR",
      "message": "Server error"
    }
  ]
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.chargebackstop.com/developer/api-documentation/simulations.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
