# 

An **integration** is the processor configuration attached to a client. Without
one, transactions for that client have nowhere to go.

| Processor | Handles | Payload |
|  --- | --- | --- |
| `Tsys` | Card | 40 fields, 29 of them required |
| `Vericheck` | ACH | Two credentials |


A client can hold both. The payment method on each transaction decides which one
runs, so nothing in the transaction request names a processor.

## Before you start

* Your reseller `Api-Key` and `Client-Id` — see [Authentication](/docs/get-started/authentication)
* The client ID to attach the integration to
* The processor's onboarding data, which comes from the processor, not from us


## Spelling the processor is case-sensitive

Get this wrong and the request fails before anything else is read.

| Where | Spelling |
|  --- | --- |
| `processor` in a request body | `Tsys`, `Vericheck` |
| `integration` as a report filter | `TSYS`, `VERICHECK` |
| `integrations` on a transaction response | `TSYS`, `VERICHECK` |


Sending `TSYS` in a body returns `400`. The gateway does not normalize it.

## Add a TSYS integration

**Twenty-nine of the forty fields in `integration_details` are required**, so the
example above is close to a minimum rather than a generous illustration. Assemble
the values from the merchant's TSYS setup before you start; they are not things
you can invent or default.

Fourteen of them carry a `maxLength` that matches a TSYS G3v088 field width —
`name` is 25 characters, `address1` is 32, `descriptor_state` is 2. Exceeding one
returns `400`, and the limits come from the processor's wire format rather than
from us.

```json 200 application/json
{
  "id": "INTEGRATION-01KFDKXMQ637EKEAY410MSQSXB",
  "is_active": true,
  "client": "CLIENT-01KFDKXMQ637EKEAY410MSQSXB",
  "processor": "Tsys",
  "integration_details": {
    "name": "Acme Jewelry LLC",
    "dba": "Acme Jewelry",
    "url": "https://example.apiserver.com",
    "phone_number": 17035550123,
    "fax_number": "+17035550199",
    "mid": "888000001234",
    "amex_number": "1234567890",
    "association": "VISA",
    "bin": "431940",
    "discover_number": "601100999999",
    "mcc": "5944",
    "bank_number": "1234",
    "industry": "R",
    "amex_opt_blue": true,
    "agent_chain": "012345",
    "store_number": "0001",
    "mvv": "123456",
    "terminal_number": "0001",
    "agent_bank_number": "123456",
    "agent_chain_number": "654321",
    "descriptor_postal": "22150",
    "descriptor_city": "Springfield",
    "descriptor_state": "VA",
    "descriptor_country": "US",
    "descriptor_phone": 17035550123,
    "descriptor_store_number": "0001",
    "address1": "123 Main St",
    "address2": "Suite 100",
    "descriptor_line3": "ACME JEWELRY 703-555-0123",
    "terminal_id": "00000001",
    "v_number": "V1234567",
    "settlement_time": "23:00",
    "merchant_area_code": 703,
    "descriptor_area_code": 703,
    "sharing_group": "AEFGKMQ",
    "merchant_aba_number": "123456789",
    "merchant_settlement_agent_number": "1234",
    "reimbursement_attribute": "0",
    "fcsid": "12345",
    "created_by": 1042,
    "created_at": "2026-02-11T09:24:17Z",
    "modified_by": 1042,
    "modified_at": "2026-06-30T14:02:51Z"
  },
  "correlation_id": "01KFDKXMQ637EKEAY410MSQSXB"
}
```

```json 400 application/json
{
  "error_code": "INVALID_REQUEST_DATA",
  "error_message": "The API request contains invalid data.",
  "details": {
    "amount": "Invalid amount",
    "payment_method.pan": "Malformed PAN"
  },
  "source": {
    "system": "TSYS",
    "code": "13",
    "message": "Invalid amount"
  }
}
```

```json 401 application/json
{
  "error_code": "NOT_AUTHENTICATED",
  "error_message": "Access credentials missing or invalid.",
  "details": null,
  "source": {
    "system": null,
    "code": null,
    "message": null
  }
}
```

```json 403 application/json
{
  "error_code": "UNAUTHORIZED_ACTION",
  "error_message": "Requested action is unavailable or forbidden.",
  "details": null,
  "source": {
    "system": null,
    "code": null,
    "message": null
  }
}
```

```json 409 application/json
{
  "error_code": "DUPLICATE_ACTION",
  "error_message": "Duplicate action requested.",
  "details": null,
  "source": {
    "system": "TSYS",
    "code": "12",
    "message": "Invalid transaction"
  }
}
```

```json 500 application/json
{
  "error_code": "SYSTEM_ERROR",
  "error_message": "Internal system error.",
  "details": null,
  "source": {
    "system": "TSYS",
    "code": "96",
    "message": "System malfunction"
  }
}
```

Keep `id` from the response. It is what you quote to update or read the
integration later.

## Add a VeriCheck integration

VeriCheck asks for far less: `client_id` and `client_secret`, both issued by
VeriCheck.

```json
{
  "client": "CLIENT-01KFDKXMQ637EKEAY410MSQSXB",
  "is_active": true,
  "processor": "Vericheck",
  "integration_details": {
    "client_id": "vc_merchant_id",
    "client_secret": "vc_merchant_secret"
  }
}
```

These are the merchant's VeriCheck credentials, and they are secrets. Treat the
request the way you would any credential transfer.

## Update an integration

`POST /v1/integrations/{id}` — a POST again, with `is_active`, `processor` and
`integration_details` all required.

**This is not a partial update.** Unlike a client update, the integration update
asks for the full trio every time, so read the integration first and send back a
complete `integration_details` with your changes applied. Sending a partial
object will fail on the missing required fields.

Note also that `client` appears on the create request but not on the update — an
integration cannot be moved to a different client.

## Turn an integration off

Set `is_active` to `false`. There is no delete.

That is how you stop a merchant processing on one rail while leaving the other
alone, and how you decommission a merchant without losing its transaction
history.

## Next steps

* [Client reports](/docs/platforms/client-reports) — read integrations back
* [Accept a card payment](/docs/payments/accept-a-card-payment)
* [Accept an ACH payment](/docs/payments/accept-an-ach-payment)