# Code and Formats
source: https://developer.mastercard.com/mastercard-threat-intelligence/documentation/code-and-formats/index.md

This page describes the codes and formats the Mastercard Threat Intelligence
(MTI) API uses. It explains the HTTP status codes you may receive, the structure
of error responses, and how to recover from common errors.

Errors can happen at two stages:

* **Authentication**: your application requests an access token from the OAuth 2.0 token endpoint. OAuth is a standard for authorizing access.
* **Resource**: your application calls an MTI API endpoint with the token.

The two stages return different error shapes, so this page covers each one.

## HTTP Status Codes and Reason Codes {#http-status-codes-and-reason-codes}

The MTI API returns a small, predictable set of status codes. The `error` field
in the body is the reason code. It is a unique constant that identifies the error
case.

### MTI API Responses {#mti-api-responses}

| HTTP status code |              Reason Code              |                     Response Description                     |                                     Resolution Tips                                     |
|------------------|---------------------------------------|--------------------------------------------------------------|-----------------------------------------------------------------------------------------|
| 200 OK           | Not applicable                        | The request succeeded. The body contains the requested data. | No action needed. For the domains endpoint, still check the `status` of each report.    |
| 400 Bad Request  | `BAD_REQUEST`                         | A field or value in the request is invalid.                  | Read the `error_description`, fix the named field, then resend the request.             |
| 403 Forbidden    | `THREAT_INTELLIGENCE_FORBIDDEN_ERROR` | Your project cannot access the requested feature.            | Confirm your project has access to that feature. If access was granted recently, retry. |

### OAuth 2.0 Token Endpoint Responses {#oauth-20-token-endpoint-responses}

These errors happen during authentication, before you reach the MTI API. They
follow the standard OAuth 2.0 error format.

| HTTP status code |    Reason Code    |                 Response Description                  |                     Resolution Tips                     |
|------------------|-------------------|-------------------------------------------------------|---------------------------------------------------------|
| 400 Bad Request  | `invalid_scope`   | The requested scope is not valid for your project.    | Request only the scopes granted to your project.        |
| 400 Bad Request  | `invalid_request` | The token request is missing a value or is malformed. | Confirm the token endpoint, issuer, and request format. |
| 401 Unauthorized | `invalid_client`  | Client authentication failed.                         | Check your client ID, key ID, and signing key.          |

### Other HTTP Responses {#other-http-responses}

You may also receive standard HTTP responses that the API does not define with a
reason code. Handle them with general HTTP practices.

* `401 Unauthorized`: your access token is missing or expired. Request a new token, then retry.
* `429 Too Many Requests`: you sent too many requests. Wait, then retry with a backoff.
* `500 Internal Server Error` or `503 Service Unavailable`: a temporary server problem. Retry later with a backoff.

## Gateway Error Codes {#gateway-error-codes}

Apart from the error codes returned by the MTI API, error codes can be returned by the Mastercard gateway, which verifies your request's signature and routes to the correct location.

For further information about the 4xx response codes returned by the gateway and their possible resolutions, see [Gateway Error Codes](https://developer.mastercard.com/platform/documentation/errors-and-troubleshooting/oauth2-error-codes/).

## Error Structure {#error-structure}

When the MTI API rejects a request, it returns a single JSON error object. It does
not return an array of errors.

### Fields {#fields}

|        Field        |  Type   |                                   Description                                   |
|---------------------|---------|---------------------------------------------------------------------------------|
| `source`            | string  | The Mastercard application that generated the error. It identifies the feature. |
| `error`             | string  | The reason code. A unique constant that identifies the error case.              |
| `error_description` | string  | A short, human-readable description of the error.                               |
| `recoverable`       | boolean | Whether retrying the same request could change the outcome.                     |

The MTI API does not return a nested `details` array. The `error_description`
carries the specific field or value that caused the error.

The `source` value tells you which feature returned the error.

|           `source` value           |                Feature                |
|------------------------------------|---------------------------------------|
| `threat-intelligence-merchant`     | Merchant Threat Intelligence          |
| `threat-intelligence-peti`         | Payment Ecosystem Threat Intelligence |
| `threat-intelligence-card-testing` | Card Testing                          |

### Single Error Example {#single-error-example}

A single error object looks like this:

```json
{
  "source": "threat-intelligence-card-testing",
  "error": "BAD_REQUEST",
  "recoverable": false,
  "error_description": "Field 'page.limit' must be greater than 0."
}
```

To parse an error, read the fields in this order:

1. Check the HTTP status code to learn the category of the problem.
2. Read `error` to identify the exact case in your code.
3. Read `error_description` to find the field or value to fix.
4. Use `recoverable` to decide whether a retry makes sense.

### Multiple Results and Partial Failures {#multiple-results-and-partial-failures}

Search endpoints return a single error object when the whole request fails. The
Merchant Threat Intelligence domains endpoint is different. It can return
`200 OK` while reporting a failure for one domain in the list.

Each report carries a `status` of `PASSED` or `FAILED`. A `FAILED` report means
the API could not evaluate that one domain, even though the request succeeded.

```json
{
  "reports": [
    {
      "domain": "good-merchant.com",
      "status": "PASSED",
      "risksFound": 0,
      "totalRisks": 9
    },
    {
      "domain": "error.com",
      "status": "FAILED"
    }
  ]
}
```

Always check the `status` of each report before you use its data.

## Sample Errors {#sample-errors}

Each example below shows a real error, why it happens, and how to recover. The
guidance is specific to the endpoint.

### Merchant Threat Intelligence: `POST /exposures/domains` {#merchant-threat-intelligence-post-exposuresdomains}

The request used a reason that is not allowed. The `reason` field must be one of
the accepted values.

```json
{
  "source": "threat-intelligence-merchant",
  "error": "BAD_REQUEST",
  "recoverable": false,
  "error_description": "Invalid reason: MERCHANT_UNDERWRITING - must be one of [MERCHANT_UNDERWRITING_CONCERNS, COLLUSIVE_MERCHANT, SCAM_MERCHANT]"
}
```

Recovery steps:

1. Set `reason` to one of `MERCHANT_UNDERWRITING_CONCERNS`, `COLLUSIVE_MERCHANT`, or `SCAM_MERCHANT`.
2. Confirm your `domains` list has 1 to 50 valid domain names.
3. Resend the request. This error is not recoverable by retry alone.

### Payment Ecosystem Threat Intelligence: `GET /exposures/vulnerabilities` {#payment-ecosystem-threat-intelligence-get-exposuresvulnerabilities}

The `search_text` value was too long. The field accepts 1 to 256 characters.

```json
{
  "source": "threat-intelligence-peti",
  "error": "BAD_REQUEST",
  "recoverable": false,
  "error_description": "Field 'filters.searchText' must be between 1 and 256 characters"
}
```

Recovery steps:

1. Shorten `search_text` to 256 characters or fewer.
2. Confirm `limit` is between 1 and 500 and `sort_direction` is `ASC` or `DESC`.
3. Resend the request.

### Card Testing: `GET /threats/card-testings/filter-options` {#card-testing-get-threatscard-testingsfilter-options}

The `type` query parameter was missing or invalid. It is required and must be one
of the accepted values.

```json
{
  "source": "threat-intelligence-card-testing",
  "error": "BAD_REQUEST",
  "recoverable": false,
  "error_description": "Field 'type' must be one of [OBSERVED_TESTING, TESTING_BEHAVIORS, TRANSACTIONS]"
}
```

Recovery steps:

1. Set `type` to `OBSERVED_TESTING`, `TESTING_BEHAVIORS`, or `TRANSACTIONS`.
2. Resend the request.

### Card Testing Searches: `POST /threats/observed-testings/searches` {#card-testing-searches-post-threatsobserved-testingssearches}

The pagination value was invalid. This pattern applies to the observed testing,
testing behaviors, and transactions search endpoints.

```json
{
  "source": "threat-intelligence-card-testing",
  "error": "BAD_REQUEST",
  "recoverable": false,
  "error_description": "Field 'page.limit' must be greater than 0."
}
```

Recovery steps:

1. Set `page.limit` to a value between 1 and 500.
2. Set `page.offset` to zero or a positive number.
3. Resend the request.

### Access Denied: Any Endpoint {#access-denied-any-endpoint}

Your project does not have access to the requested feature. This error can occur
on any endpoint.

```json
{
  "source": "threat-intelligence-card-testing",
  "error": "THREAT_INTELLIGENCE_FORBIDDEN_ERROR",
  "recoverable": true,
  "error_description": "Access Denied"
}
```

Recovery steps:

1. Confirm your project has access to the feature you called.
2. Confirm the scopes in your token request match the feature.
3. If access was granted recently, wait a short time, then retry. This error is marked recoverable.

## ISO Country and Currency Codes {#iso-country-and-currency-codes}

The MTI API follows the Mastercard API standards for currency codes. The
`currencyCode` field on a transaction uses ISO 4217 alpha-3 codes, such as `USD`.
No custom currency codes are used.

## Date and Time Formats {#date-and-time-formats}

The MTI API follows the Mastercard API standards for dates and times. All
date-time values use ISO 8601 format in Coordinated Universal Time (UTC), such as
`2025-10-21T12:34:56Z`. The trailing `Z` marks UTC. No custom date formats are
used.

## Next Steps {#next-steps}

Still have questions? Visit the [Support](https://developer.mastercard.com/mastercard-threat-intelligence/documentation/support/index.md) page to browse FAQs or get help from the support team.
