# home
Source: https://docs.synctera.com/home
Welcome to Synctera's docs
Explore our documentation to learn how to quickly and easily build a FinTech app or embedded banking product with Synctera.
Search or ask
## Get started
> [card] [API keys and sandbox](https://app.synctera.com/)
>
> Create a Synctera account to get your API key, access our sandbox, and explore the rest of our Console.
>
> [ Sign up](https://app.synctera.com/)
## Explore our documentation
> [card] [API Guides](/docs/platform-overview)
>
> Learn everything you need to know about integrating with our APIs and how to make your use case come to life.
>
> [View the API Guides](/docs/platform-overview)
> [card] [API Reference](/reference/introduction)
>
> Everything you need to make your project come to life can be found here.
>
> [View the APIs](/reference/introduction)
## Dive into our APIs
> [tab] Core
>
> > [card] [Personal Customers](/docs/create-a-personal-customer)
> >
> > Creates and manages records for personal customers
>
> > [card] [Business Customers](/docs/create-a-business)
> >
> > Creates and manages records for business customers
>
> > [card] [Accounts](/docs/create-accounts-guide)
> >
> > Creates and manages customer accounts
>
> > [card] [Cards](/docs/personal-cards)
> >
> > Issues, activates, and manages cards for customers
> [tab] Payments
>
> > [card] [Internal Transfers](/docs/internal-transfer-guide)
> >
> > Transfer funds between two accounts in real-time
>
> > [card] [Payment Schedules](/docs/payment-schedules)
> >
> > Create and manage scheduled payments for customers
>
> > [card] [ACH Payments](/docs/ach-guide)
> >
> > Issue cards, accept payments, and transfer money between accounts
>
> > [card] [mRDC (Remote Deposit Capture)](/docs/create-mobile-deposit-guide)
> >
> > Handles remote deposit capture (RDC) transactions
> [tab] Risk & Compliance
>
> > [card] [KYC/KYB Verification](/docs/kyc-kyb-verification)
> >
> > Create and manage documentation for a customer and run verification checks
>
> > [card] [Document Verification](/docs/document-verification)
> >
> > Verify documentation for a customer
>
> > [card] [Disclosures](/docs/record-disclosure-acceptance)
> >
> > Handles legally required disclosures to customers
# ACH Payments
Source: https://docs.synctera.com/v2/docs/ach-guide
If you’re building a service that will enable your customers to send and accept payments, issue cards, or transfer money between accounts at different institutions, chances are you’ll need ACH. ACH is a one-stop shop for a variety of payment use cases.
From recurring payments and payroll deposits to online purchases and bill payment, ACH offers a fast and flexible way to send money.
Originally established in 1970, expanding support and innovation around ACH payments has led it to become one of the most popular online payment rails in the world.
## What is an ACH Transaction?
An ACH transaction (often referred to as an ACH transfer) is an electronic, bank-to-bank money transfer processed through the Automated Clearing House (ACH) Network. You can think of the ACH Network as a postal service for ACH files. Each file can contain up to 1000 ACH entries with each entry representing a transaction being sent from one bank to another.
ACH transactions can be used to facilitate Person-to-person (P2P), Business-to-consumer (B2C), and Business-to-business (B2B) payments and is a convenient alternative to card networks, wire transfers, paper checks or cash. In addition to their convenience, ACH transactions are reliable, inexpensive, fast, and most importantly, safe. Most transfers are processed and settled within 1-2 business day with zero cost to the consumer.
See our [ACH Transfers - Risk and Compliance](/docs/ach-payments-risk-and-compliance) guide for more details on risks and controls, account validation, and NACHA requirements surrounding return rates.
## What are the 2 types of ACH Transactions?
Each ACH transaction involves 2 primary parties:
1. The **Originating Depository Financial Institution (ODFI)** which is the bank initiating the transaction; and
2. The **Receiving Depository Financial Institution (RDFI),** the bank receiving the transaction.
All transactions fall into one of two categories, debit (“pull”) or credit (“push”).
### Push (Credit)
Determining if a transaction is a push or pull is always with respect to the receiving account. For example, if Tom, a customer of Bank A wants to send money to John, a customer of Bank B. Tom’s bank can originate an ACH push transaction from his account to John’s account. The term “push” is used interchangeably with “credit”. The result is a credit to John’s (the receiver) account balance and a debit to Tom’s (the sender).
A real life use case for push transactions are the deposits that result from an employee signing up for payroll direct deposit. Whenever payday rolls around, the employer’s bank initiates a push/credit to the employee’s bank account.
### Pull (Debit)
Alternatively, if Tom want’s to request money from John, Tom’s bank can originate an ACH pull request from his account to John’s. The term “pull” is used interchangeably with “debit”. The result is a debit to John’s account and a credit to Tom’s. This is what occurs when users of a service sign up for recurring bill payments. The service provider ends up debiting the customer’s account via an ACH pull request.
This is also the case when a banking customer deposits a check made out to him/her by an account holder at another financial institution. Checks are ultimately translated into pull request on the ACH network. The check contains the account holders routing and account number which are the only pieces of information required to initiate a credit or debit from an account at another institution.
> [!NOTE]
>
> There is a difference between the direction of an ACH transaction and the direction of money flow. The direction of the transaction refers to the direction of the ACH message on the network. It always flows from the originator to the receiver while the direction of money flow relates to which account is receiving funds and which account is sending them. This means there are 2 ways to achieve the same direction of money movement.
## Scenario
The desired result is to withdraw funds from an account at **Bank A** and deposit them into an account at **Bank B**

### Option 1 (This is how customers fund their accounts)
Bank B sends an ACH **debit / pull** transaction requesting funds from the account at Bank A:

### Option 2
Bank A sends an ACH **credit / push** transaction to send funds to the account at Bank B.

## How does Synctera support ACH?
From the outside, the ACH workflow may seem simple, but it’s actually quite complex. This is where Synctera comes in. Synctera works with your sponsor bank to serve as your connection to the ACH network and supports sending and accepting ACH transactions from other financial institutions.
In ACH terms, Synctera acts as the **ODFI** (Originating Depository Financial Institution) when it comes to originating transactions and the **RDFI** (Receiving Depository Financial Institution) when it comes to receiving them. It means that we take care of all the batch processing and file generation while ensuring that all transactions are reflected in your customer account balances.
### FinTech in the Auth Flow
Synctera allows the FinTech to participate in the transaction authorization decision for Inbound ACH Direct Debit.
This capability can only be enabled for linked zero balance accounts and can be used to:
* Restrict payments to certain institutions
* Run your own balance checks against the linked balance carrying account
If the transaction is declined by the FinTech, then an ACH return will be sent to the network.
The FinTech does not have to participate unless there is an additional approval logic. If the FinTech opts not to participate in the Auth Flow, Synctera will use default authorization logic to authorize the transactions.
In order to participate in Auth Flow for Pull (Debit) ACH transactions, the FinTech should support an **Authorization Gateway** and a corresponding **Gateway Endpoint** must be configured on the Synctera side.
#### Authorization Gateway
An authorization Gateway enables a FinTech to optionally take part in the decision of a Pull (Debit) ACH transaction’s authorization cycle. The FinTech receives an authorization request via the configured Gateway to either **approve** or **decline** corresponding ACH transactions based on the FinTech's own business logic.
**Request Body**
Synctera sends such information as a `POST` HTTP request to the FinTech about Pull (Debit) ACH transactions that needs to be authorized:
```json JSON theme={"system"}
{
"customer_id": "2b9cc6f2-d0bd-4d9d-aa20-5e53355f9469",
"account_id": "0221e0a7-7774-48a4-8521-e678ec09a53a",
"transaction_id": "9b59fc80-9bf5-4749-8dd2-511f183becf2",
"settlement_date": "2022-03-25",
"effective_date": "2022-03-25",
"transaction_type": "incoming_debit",
"dc_sign": "debit",
"amount": 100,
"currency": "USD",
"network": "ACH",
"company_entry_description": "ACCTVERIFY",
"company_name": "PAYPAL"
}
```
**Response HTTP code**
To signal an authorization request decision, the FinTech must reply with the appropriate HTTP code:
* HTTP code `200`: **approve** the corresponding ACH transaction
* HTTP code `402`: **decline** the corresponding ACH transaction
Receiving any other HTTP code in the response will stop the processing of the corresponding Pull (Debit) ACH transaction. However, in this case the transaction will ***not be declined***, but will be ***retried within 2 days*** until the FinTech responds with either `200` or `402` response.
**Response timeout**
Synctera waits for the authorization response within the timeout window which **defaults to 1.5 seconds**, but can be configured in the **Gateway Endpoint Configuration**.
If the response is not received within the defined timeout window, the corresponding Pull (Debit) ACH transaction will stop being processed. But will ***not be declined*** and will be ***retried with exponential backoff*** until the FinTech sends the response within the defined timeout window. If no response is given within the retry window (default: 35 minutes, configurable per bank/partner via `auth_retry_config`), the ACH will be sent to suspense for a manual review by Payment Operations.
#### Gateway Endpoint Configuration
To configure a Gateway for the FinTech, a valid publicly accessible `url` must be provided.
Additionally, `custom_headers` and custom response timeout in milliseconds `max_wait_ms` can be configured. Also, Gateways may be disabled by setting the `disabled` field to `true`.
```sh Shell theme={"system"}
curl \
-X POST \
-H "Authorization: Bearer $apikey" \
-H "Content-Type: application/json" \
$baseurl/v0/ach/gateways \
--data-binary '
{
"url": "https://example-fintech.com/ach/auth",
"custom_headers": {
"key1": ["value1", "value2"],
"key2": ["value"]
},
"max_wait_ms: 1500,
"disabled": false
}'
```
## How are accounts funded using ACH?
Once your customers have an account setup, they’ll need to fund their account by originating an ACH pull/debit transaction to be sent to their account at another institution. Synctera refers to this as an [external account](/v2/docs/external-accounts-guide).
If you have just created account B on the Synctera platform and you want to add funds to it from account A at another financial institution, its natural to assume that funding involves *pushing* funds from account A to account B. Instead, funding your customers account involves originating an ACH debit/pull transaction with your Synctera account in order to withdraw funds from the external account.
## How do I get started with sending/receiving ACH payments?
### Step 1: Customer Creation
1.1 **Create a Customer**
Any individual wanting to transact on the Synctera platform must be stored as a customer in our system. Part of that includes completing the KYC process. See the [Customer guide](/v2/docs/create-a-personal-customer) for details.
### Step 2: Account Creation
2.1 **Create an Account**
In order to send and receive ACH payments you will need to create an account and associate it with your customer. [Account Guide](/v2/docs/create-accounts-guide)
2.2 **Create an External Account**
In order for your customers to fund their accounts they’ll need to debit funds from an account at another institution. You'll need to create an external account on the Synctera platform which serves as the internal representation of the account to be debited. [External Account Guide](/v2/docs/external-accounts-guide)
### Step 3: Send/Receive an ACH
3.1 **Send an ACH request**
Once the external account has been verified, ACH transactions (credits and debits) can be originated from your customer’s account. If you’re unsure what values to set in your API request take a look at the documentation [here](/v2/reference/addtransactionout).
3.2 **Receive an ACH transaction**
As long as your customer has an account that is both active and verified, there is no work required by you or your customer to receive ACH transactions. Synctera will process the incoming transaction and debit/credit the account accordingly.
## What happens after I send an ACH request?
After you send a request to originate an ACH transaction, the transaction is placed in a batch which, in turn, is placed in an ACH file to be sent out over the network. Depending on the time that you originate the transaction there may be some delay between the time the transaction is created and the time the file is sent. This is done to align with the [processing schedule](https://www.frbservices.org/resources/resource-centers/same-day-ach/fedach-processing-schedule.html) set by the federal reserve. The date the transaction is sent will ultimately determine when funds are settled across accounts and institutions. It will also have a bearing on if and when an ACH transaction can be returned by the recipient.
The responsibilities and guidelines for participants in the ACH system are determined by the National Automated Clearing House Association, better known as NACHA. NACHA operates as the rule making body for all financial institutions wanting to use the ACH system.

## What do I need to do to receive an ACH transaction?
Nothing. Unless an incoming transaction needs to be returned (see [Why would an ACH transaction be returned?](#why-would-an-ach-transaction-be-returned)), no action is required. Synctera will process all debit and credits for any ACH transactions that we receive on behalf of you or your customers. Check your Synctera dashboard to view all ACH transaction that have been sent or received. Synctera also supports webhooks to notify you of all ACH transactions.
## How long does it take to process an ACH transaction?
The time it takes for the network to completely process an ACH transaction is dependent on a number of variables. The operating schedule of the federal reserve, the operating schedule of each bank, and the time of day the transaction was created are all key factors in determining when a transaction will settle. “Settle”. Integrators can influence the timing of an ACH transaction by setting the `is_same_day` field to `true` when posting a request to send a transaction.
However, even when sending “same day” ACH transfers, there are a couple things to keep in mind:
* Transactions can be returned up to 2 business days after the settlement day. This introduces risk for fintech’s who choose to make funds immediately available to account owner who have initiated a pull request. The ACH system operates on a “no news is good news” basis. The absence of a return within the 2-day timeframe typically means that the RDFI has accepted the transaction.
* “Same day” ACH is only available within certain transmission windows set by the federal reserve. Take a look at the Fed [processing schedule](https://www.frbservices.org/resources/resource-centers/same-day-ach/fedach-processing-schedule.html) for more information on cut off times. In general, transactions submitted (Mon-Fri) by 4:45pm are eligible to settle on the same day. “Same day” is not available on non-banking days (weekends and holidays) and will automatically default to the next available “banking day”.
* Submitting incorrect information may cause processing errors that result in delays. Errors may also increase the likelihood of a transaction being returned.
## Why would an ACH transaction be returned?
ACH transactions can be returned for a variety of reasons. “Insufficient funds”, “invalid account number”, “account closed” are all fair game but but many of the return reasons are not so obvious. NACHA guidelines specify [85 different codes](https://engineering.gusto.com/how-ach-works-a-developer-perspective-part-2/#appendix) that may be associated with a returned transaction. The good news is that you and your customers are likely to see only the most common ones. Synctera will take care of processing any returned transaction and notify you of the resolution via webhooks. In the event that a returned transaction requires your immediate attention, you will be able to take action through the Synctera dashboard.
The dashboard is also were you can generate returns from received ACH transactions. While most transaction failures such as insufficient funds, invalid account, etc., will result in automatic returns, you may occasionally identify transactions that were not authorized and choose to manually initiate a return.
## ACH same day vs non-same day cut-off times
| ACH Type | Cut-off time | Comments |
| - | - | - |
| Same day | 4:45 pm ET (1:45 pm PT) (Monday - Friday) | Same day ACH payments with effective date of today submitted before 4:45 pm ET will be processed as ‘same day’ ACH |
| Non-Same day | 24:00 pm ET (Monday-Friday) | Non same ACH payments with effective date of tomorrow or 2 days in the future submitted before 24:00 will be processed as ‘non-same day’ |
**ACH (Debit/Credit) - External bank to Synctera account**
| ACH Type | File processing time | Comments |
| - | - | - |
| Same day | 10:30 am ET2:45 pm ET4:45 pm ET | ACH Batch files with same day payments (debits/credits/returns) directed to Synctera accounts will be processed at these times |
| Non same day / future dated ACH | 10:30 am ET2:45 pm ET4:45 pm ET8:00 pm ET \*2:15 am ET \* | ACH Batch files with non-same day payments (debits/credits/returns) directed to the Synctera accounts will be processed at these times |
> [!NOTE]
>
> Not all of our sponsor banks support 8:00 pm ET / 2:15 am ET exchange times
**ACH Returns - External bank to Synctera account**
| Return code | Days from original transaction |
| - | - |
| **R01:** NSF | 2 Banking Days |
| **R02:** Account closed | 2 Banking Days |
| **R03:** No Account - Account number structure is valid, but doesn't match individual or Open account | 2 Banking Days |
| **R04:** Invalid Account - Account number structure not valid, ie edit check digit or number failed | 2 Banking Days |
| **R05:** Unauthorized Debit to Consumer Account Using Corporate SEC Code - A Debit entry that uses a corporate SEC code was transmitted to a consumer but was not authorized by the consumer | 60 Calendar Days |
| **R07:** Authorization Revoked - Customer who previously authorized an entry claims, authorization has been revoked from the Originator | 60 Calendar Days |
| **R08:** Payment Stopped: The customer has requested the stop payment of a specific ACH Debit Entry | 2 Banking Days |
| **R09:** Sufficient ledger balance exists, but value of uncollected items brings available balance below amount of debit entry | 2 Banking Days |
| **R10:** Customer Advises Not Authorized, Improper, Ineligible, Part of Incomplete transaction or Improperly reinitiated - Not authorized, wrong amount, debit date before authorized, incomplete transaction, improper source document or exceeds reinitiating attempt | 60 Calendar Days |
| **R12:** Account sold to another FI | 2 Banking Days |
| **R16:** Account frozen/Entry Returned Per OFAC Instruction - Access to account is restricted due to action by the bank | 2 Banking Days |
| **R20:** Non-transaction Account - Policies and regulations restrict activity to account indicated | 2 Banking Days |
| **R24:** Duplicate Entry - Entry is a duplication. The trace number, date, dollar amount, etc. match another entry | 2 Banking Days |
| **R29:** Corporate Customer Advises Not Authorized | 2 Banking Days |
| **R31:** Permissible Return Entry - Sender bank agreed on behalf of the Originator to accept a return after the deadline for an unauthorized corporate entry | Undefined |
| **R37:** Source document Presented for Payment - The source document to which an ARC or BOC or POP entry relates has also been presented for payment | 60 Calendar Days |
| **R38:** Stop Payment of Source Document - A Stop Payment has been placed on the source document to which the ARC or BOC Entry relates. | 60 Calendar Days |
| **R39:** Improper Source Document/Source Document presented for payment - The RDFI determines the source document for the ARC, BOC or POP entry is not an eligible item or was presented for payments | 2 Banking Days |
| **R50:** State Law Affecting RCK Acceptance - RDFI is located in a state that has not adopted Revised Article 4 of the UCC or RDFI is located in a state that requires all canceled checks to be returned to the receiver | 2 Banking Days |
| **R51:** Item is Ineligible, Notice Not Provided, Signatures not Genuine, Item Altered or Amount of RCK Not Accurately Obtained from the Item | 60 Calendar Days |
| | |
## Company Entry Description
As of March 20, 2026, NACHA dictates that ACH transactions meeting the requirements for Payroll or Purchase transactions are required to be classified in the Company Entry Description as such:
`PAYROLL`: wages, salary, or other similar types of compensation for labor or services. `PURCHASE`: e-commerce purchases authorized by a consumer receiver for the online purchase of goods. This does not include recurring bills such as utilities, mortgages or other types of bill payments.
If sending a Payroll or Purchase payment via Synctera ACH, include the `PAYROLL` or `PURCHASE` descriptor in the `company_entry_description` field accordingly.
## Example: Funding a customer account
To fund a customer account from an external bank account the Synctera API:
```shell shell theme={"system"}
curl \
-X POST \
-H "Authorization: Bearer $apikey" \
-H "Content-Type: application/json" \
https://api.synctera.com/v0/ach \
--data-binary '
{
"risk": {
"client_ip": "127.0.0.1"
},
"customer_id": "{CUSTOMER_ID}",
"amount": 100,
"currency": "USD",
"receiving_account_id": "{EXTERNAL_ACCOUNT_ID}",
"dc_sign": "debit",
"originating_account_id": "{ACCOUNT_ID}",
"reference_info": "Synctera test",
"memo": "Synctera test"
}'
```
It is important to note a few things in this example:
1. The `receiving_account_id` always refers to an [External Account](/v2/docs/external-accounts-guide).
2. The `originating_account_id` always refers to to an [Account](/v2/docs/create-accounts-guide).
3. The `dc_sign` is always from the perspective of the **receiving** account. So a `debit` to the receiving account results in a credit to the originating account.
4. The `amount` is always in the smallest denomination of the given currency. In this case, the currency is `USD`, which means the amount is in cents.
5. The `customer_id` indicates the person that is making the outgoing ACH request. This customer must be an account holder or authorized signer of `originating_account_id`
## **Understanding ACH Holds**
Outgoing ACH Debits by default will have a 2 day hold applied to reduce the risk of returns. Depending on Sponsor Bank approval and program risk, that global hold may be reduced in some circumstances.
There is a **hold object** within the ACH request that can further configure certain ACH transactions to have custom hold logic. Within the hold object, there are two fields:
* `hold.duration `- Fintechs can set custom hold durations for individual ACHs or for certain use cases. Note that a lower hold duration than the global setting in the API request will not be honored unless Early Funds Availability is set in the global configuration (subject to Sponsor Bank approval). If hold.duration is 0 in this case, the funds will be released immediately.
* `hold.amount` - this is the amount of the transaction that will be held if the hold duration is applied.
Applying the hold object can be used to apply partial or full holds to ACHs that otherwise would default to the global logic. For example, in some cases, fintechs may want to apply a full two day hold; in other cases, they may want to release the funds immediately. In yet other cases, they may want to make available a partial amount, putting the rest on hold until the hold duration has cleared. This is all possible by leveraging the ACH hold object.
### **Scenarios and Examples:**
### **Applying higher holds to certain customer segments or use cases**
Globally, Fintech A and Fintech B both have a Sponsor-Bank-approved 1 day hold for all transactions. \
\
**Applying full amount holds on individual ACHs**\
Fintech A wants initial funding transactions to be as fast as possible, to streamline the onboarding process and get customer funds available for spend quickly. For other ACHs, the standard 2 day holds should be applied to reduce overall return risk. \
\
**Example:** John Consumer already initially funded his account and decides to pull in the rest of his funds at their external bank to start using his Fintech A account as primary. \
In this case, Fintech A should send the initial funding ACH with no hold object set (inheriting the global hold of 1 day), and all subsequent ACHs should contain the hold object, with the `hold.amount` as the full amount of the transaction and the `hold.duration` as 2.
**Request:**
> \{
>
> "tenant": "14\_23",
>
> "amount": 534023,
>
> "currency": "USD",
>
> "dc\_sign": "debit",
>
> "customer\_id": "412b7250-c21d-45ea-9e3b-f0d4468bfd36",
>
> "originating\_account\_id": "65147f26-9b1b-4afe-887d-0716310144a8",
>
> "receiving\_account\_id": "b4323a31-4ed4-4689-87e4-0a0c70d3f0a6",
>
> "is\_same\_day": true,
>
> "memo": "not an initial funding transaction",
>
> "hold": \{
>
> "amount": 534023,
>
> "duration": 2
>
> }
>
> }
**Response:**
> \{
>
> "account\_id": "b4323a31-4ed4-4689-87e4-0a0c70d3f0a6",
>
> "account\_name": "John Consumer",
>
> "account\_no": "1111222233330000",
>
> "amount": 400,
>
> "bank\_id": 14,
>
> "company\_entry\_description": "Example Bank",
>
> "company\_name": "Fintech A",
>
> "effective\_date": "2026-09-21",
>
> "external\_id": "13841bf6-2f3d-4a00-87b9-54297b27951e",
>
> "id": "96f5335f-050c-4a03-b0ec-f3548ad0567e",
>
> "is\_same\_day": true,
>
> "memo": "not an initial funding transaction",
>
> "partner\_id": 23,
>
> "source\_account\_id": "65147f26-9b1b-4afe-887d-0716310144a8",
>
> "source\_account\_name": "John Consumer",
>
> "source\_account\_no": "108403030594",
>
> "status": "PENDING",
>
> "trace\_no": "234567800001513"
>
> }
### **Partial holds**
Fintech B wants to place restrictions on higher dollar ACH amounts, to reduce the risk of high dollar fraud. They want any transaction under \$300 to clear within one day, while the remainder, regardless of how much, should be put on hold for the full 2 days.\
\
Example: Jane Consumer is initiating a \$4000 transaction to fund her account. Based on the above criteria, \$300 should be available after a 1 day hold, while the remaining \$3700 should be released after a 2 day hold. In this case, Fintech A will need to calculate the amount over \$300 on each transaction and apply that as the `hold.amount`. The `hold.duration` should be 2.
\
**Request:**
> \{
>
> "tenant": "14\_23",
>
> "amount": 400000,
>
> "currency": "USD",
>
> "dc\_sign": "debit",
>
> "customer\_id": "412b7250-c21d-45ea-9e3b-f0d4468bfd36",
>
> "originating\_account\_id": "65147f26-9b1b-4afe-887d-0716310144a8",
>
> "receiving\_account\_id": "b4323a31-4ed4-4689-87e4-0a0c70d3f0a6",
>
> "is\_same\_day": true,
>
> "memo": "testing",
>
> "hold": \{
>
> "amount": 370000,
>
> "duration": 2
>
> }
>
> }
**Response:**
> \{
>
> "account\_id": "b4323a31-4ed4-4689-87e4-0a0c70d3f0a6",
>
> "account\_name": "Jane Consumer",
>
> "account\_no": "1111222233330000",
>
> "amount": 400,
>
> "bank\_id": 14,
>
> "company\_entry\_description": "Example Bank",
>
> "company\_name": "Fintech B",
>
> "effective\_date": "2026-09-21",
>
> "external\_id": "13841bf6-2f3d-4a00-87b9-54297b27951e",
>
> "id": "96f5335f-050c-4a03-b0ec-f3548ad0567e",
>
> "is\_same\_day": true,
>
> "memo": "testing",
>
> "partner\_id": 23,
>
> "source\_account\_id": "65147f26-9b1b-4afe-887d-0716310144a8",
>
> "source\_account\_name": "Jane Consumer",
>
> "source\_account\_no": "108403030594",
>
> "status": "PENDING",
>
> "trace\_no": "234567800001513"
>
> }
# Adverse Actions
Source: https://docs.synctera.com/v2/docs/adverse-actions-guide
Adverse action notices record and communicate the reasons a credit decision adversely affected a customer, as required by the ECOA and FCRA.
## Overview
Adverse action notifications are a cornerstone of regulatory compliance in financial services. Mandated by the Equal Credit Opportunity Act (ECOA) and the Fair Credit Reporting Act (FCRA), they ensure applicants are informed promptly and transparently when a decision adversely affecting them is made. The Adverse Actions API streamlines recording these notices and associating them with the application or account they concern.
**An adverse action** captures the reasons a customer was denied credit — or offered less favorable terms than requested — along with the purpose of the decision and the resource it relates to.
Key characteristics:
* **Reason-bearing** — a notice carries up to four principal `reasons` (a fifth may be required if one reason is inquiry-related).
* **Purpose-scoped** — the `purpose` records the point in the account lifecycle the decision was made (e.g. `ACCOUNT_OPENING`, `ACCOUNT_CLOSURE`).
* **Associated** — every notice is tied to an application or account via `related_resource_id` and `related_resource_type`.
* **Timely** — the notice of adverse action (NOAA) must generally be delivered within 30 days of the credit decision.
> [!NOTE]
>
> A fintech must give customers specific reasons when credit is denied or terms are less favorable than requested — typically up to four principal reasons, plus a fifth if one is inquiry-related. Adverse actions apply across the credit lifecycle: account opening denial, denied line-increase request, penalty-based APR increase, account closure, and more.
## Prerequisites
This guide assumes you are familiar with:
* [Need to Know — Environments](/v2/reference/need-to-know#environments)
* [Need to Know — Authentication](/v2/reference/need-to-know#authentication)
* Credit [applications](/v2/reference/patchapplication) and accounts
## The adverse action object
| Field | Description |
| - | - |
| `id` | Unique identifier (read-only, assigned on creation). |
| `purpose` | The lifecycle event the decision concerns (e.g. `ACCOUNT_OPENING`, `ACCOUNT_CLOSURE`). |
| `reasons` | The principal reasons for the adverse action (e.g. `TOO_MANY_INQUIRIES`, `INSUFFICIENT_CREDIT_HISTORY`). |
| `related_resource_id` | The `id` of the associated customer or account. |
| `related_resource_type` | The type of associated resource: `CUSTOMER` or `ACCOUNT`. |
| `notification_time` | When the customer was notified of the decision. |
| `creation_time` / `last_updated_time` | Timestamps (read-only). |
```json theme={"system"}
{
"id": "2fb2858b-f859-4dc8-9ad2-2a4e596fed89",
"purpose": "ACCOUNT_OPENING",
"reasons": ["TOO_MANY_INQUIRIES", "INSUFFICIENT_CREDIT_HISTORY"],
"related_resource_id": "9337a443-fa03-471c-ab05-b138c41dbd17",
"related_resource_type": "CUSTOMER",
"notification_time": "2020-05-19T21:14:27.434964Z",
"creation_time": "2023-09-19T15:48:24.10184Z",
"last_updated_time": "2023-09-19T15:48:24.10184Z"
}
```
See the [API reference](/v2/reference/createadverseaction) for the full schema.
## Recording adverse actions
### Example: a denied Line of Credit application
**1. Record the adverse action notice**
When an application to open a Line of Credit account is denied, record the notice with [POST /v2/adverse\_actions](/v2/reference/createadverseaction), scoped to the customer:
```shell theme={"system"}
curl \
-X POST \
-H "Authorization: Bearer $apikey" \
-H 'Content-Type: application/json' \
https://api.synctera.com/v2/adverse_actions \
--data-binary '
{
"notification_time": "2020-05-19T21:14:27.434964Z",
"purpose": "ACCOUNT_OPENING",
"reasons": ["TOO_MANY_INQUIRIES", "INSUFFICIENT_CREDIT_HISTORY"],
"related_resource_id": "9337a443-fa03-471c-ab05-b138c41dbd17",
"related_resource_type": "CUSTOMER"
}'
```
The response includes the system-generated `id`:
```json theme={"system"}
{
"id": "2fb2858b-f859-4dc8-9ad2-2a4e596fed89",
"purpose": "ACCOUNT_OPENING",
"reasons": ["TOO_MANY_INQUIRIES", "INSUFFICIENT_CREDIT_HISTORY"],
"related_resource_id": "9337a443-fa03-471c-ab05-b138c41dbd17",
"related_resource_type": "CUSTOMER",
"notification_time": "2020-05-19T21:14:27.434964Z",
"creation_time": "2023-09-19T15:48:24.10184Z",
"last_updated_time": "2023-09-19T15:48:24.10184Z"
}
```
**2. Link the notice to the application**
Associate the adverse action with the applicant on the Line of Credit application using [PATCH /v2/applications/\{APPLICATION\_ID}](/v2/reference/patchapplication), and move the application to `CREDIT_DENIED`:
```shell theme={"system"}
curl \
-X PATCH \
-H "Authorization: Bearer $apikey" \
-H 'Content-Type: application/json' \
https://api.synctera.com/v2/applications/{APPLICATION_ID} \
--data-binary '
{
"applicants": [
{
"adverse_action_id": "2fb2858b-f859-4dc8-9ad2-2a4e596fed89",
"customer_id": "4a666a01-d23a-47b1-8c20-2eb5a923da35",
"is_primary": true
}
],
"status": "CREDIT_DENIED"
}'
```
```json theme={"system"}
{
"id": "ebda67f0-e0a7-41e2-98ed-0617a1e815a6",
"account_type": "LINE_OF_CREDIT",
"type": "CREDIT",
"purpose": "ACCOUNT_OPENING",
"status": "CREDIT_DENIED",
"applicants": [
{
"adverse_action_id": "2fb2858b-f859-4dc8-9ad2-2a4e596fed89",
"customer_id": "4a666a01-d23a-47b1-8c20-2eb5a923da35",
"is_primary": true
}
],
"creation_time": "2022-10-26T19:14:45.861687Z",
"last_updated_time": "2023-09-20T00:31:10.255042Z"
}
```
### Example: an account closed for delinquency
When a charge-secured account is closed due to delinquency, record the notice scoped to the account with `related_resource_type` set to `ACCOUNT`:
```shell theme={"system"}
curl \
-X POST \
-H "Authorization: Bearer $apikey" \
-H 'Content-Type: application/json' \
https://api.synctera.com/v2/adverse_actions \
--data-binary '
{
"notification_time": "2020-05-19T21:14:27.434964Z",
"purpose": "ACCOUNT_CLOSURE",
"reasons": ["FRAUDULENT_ACTIVITIES"],
"related_resource_id": "9337a443-fa03-471c-ab05-c538c41dbd17",
"related_resource_type": "ACCOUNT"
}'
```
```json theme={"system"}
{
"id": "2fb2858b-f859-4dc8-9ad2-3b4e596fed89",
"purpose": "ACCOUNT_CLOSURE",
"reasons": ["FRAUDULENT_ACTIVITIES"],
"related_resource_id": "9337a443-fa03-471c-ab05-c538c41dbd17",
"related_resource_type": "ACCOUNT",
"notification_time": "2020-05-19T21:14:27.434964Z",
"creation_time": "2023-09-19T15:48:24.10184Z",
"last_updated_time": "2023-09-19T15:48:24.10184Z"
}
```
## Best practices
> [!WARNING]
>
> The notice of adverse action must generally be delivered within **30 days** of the credit decision. Record the adverse action and notify the customer promptly to stay within the regulatory window.
* **Limit to principal reasons** — provide up to four principal reasons, adding a fifth only when one reason is inquiry-related.
* **Always associate the notice** — link every adverse action to its application (`ACCOUNT_OPENING`) or account (`ACCOUNT_CLOSURE`, APR increase, etc.).
* **Set an accurate `notification_time`** — it anchors the compliance timeline; record when the customer was actually notified.
* **Cover the full lifecycle** — record adverse actions for line-increase denials and penalty APR increases, not just openings and closures.
## Related guides
> [card] [Create a Personal Customer](/v2/docs/create-a-personal-customer)
>
> The customer an adverse action is scoped to.
> [card] [Credit Applications](/v2/docs/credit-applications-guide)
>
> Link adverse actions to the applications they concern.
> [card] [Line of Credit Accounts](/v2/docs/line-of-credit-accounts-guide)
>
> The credit accounts adverse actions apply to.
## API reference
* [Create an adverse action](/v2/reference/createadverseaction)
* [List adverse actions](/v2/reference/listadverseactions)
* [Get an adverse action](/v2/reference/getadverseaction)
* [Update an application](/v2/reference/patchapplication)
# Applications
Source: https://docs.synctera.com/v2/docs/applications-guide
The Application API is used to collect applicants' data. As FinTech processes the application, they update the content and status of the application.
For different use cases, Synctera supports distinct types of applications. The current application types are:
1. Credit Applications: Used for credit products where the end-user is a consumer or a business. See details [here](/v2/docs/credit-applications-guide).
2. Restricted Account Application: Application to process special cases of Business accounts.
# Autopay
Source: https://docs.synctera.com/v2/docs/autopay-guide
Autopay lets your customers schedule automatic recurring payments toward a lending account. You define the rules once — how much, when, and from where — and Synctera creates and executes each payment.
> [!WARNING]
>
> The Autopay endpoints are in **Beta**. Feedback from the community is welcome. Synctera may make breaking changes to these endpoints.
## Overview
Autopay removes the need for your customers to remember to pay their credit balance each month. You create a single **autopay configuration** on a lending account that answers three questions:
* **How much?** — minimum due, statement balance, current balance, or a fixed amount
* **When?** — on the due date, a set number of days before the due date, or daily
* **From where?** — an internal Synctera account, or an external bank account debited via ACH
Once a configuration is active, Synctera generates an **autopay** record for each upcoming payment, recalculates the amount as balances change, executes the payment on the scheduled date, and records the outcome.
Autopay is built on two distinct resources. Keeping them straight is the key to using the API:
| Resource | Endpoint | What it is |
| - | - | - |
| Autopay configuration | `/v2/autopay_configs` | The **persistent rule**. One active configuration per lending account. You create, update, pause, and delete it. |
| Autopay | `/v2/autopays` | A **single scheduled payment** created from the rule. Synctera creates these automatically. You can read them and cancel individual ones. |
> [!NOTE]
>
> You never create an autopay record directly. Synctera creates one for each billing cycle (for `STATEMENT` autopays) or on a recurring cadence (for `SCHEDULED` autopays), based on the active configuration.
## Prerequisites
Before you create an autopay configuration, make sure the following are in place.
**1. A lending account**
Autopay applies to lending accounts — line of credit, secured charge, or unsecured charge. See [Line of Credit Accounts](/v2/docs/line-of-credit-accounts-guide), [Secured Charge Accounts](/v2/docs/secured-sc-accounts-guide), or [Unsecured Charge Accounts](/v2/docs/unsecured-charge-accounts-guide).
You will need the `lending_account_id`.
**2. A customer with an ownership relationship**
Every autopay configuration is owned by a customer — either a person (`person_id`) or a business (`business_id`). Exactly one must be provided.
That customer must hold one of the following relationships with the lending account:
* `PRIMARY_ACCOUNT_HOLDER`
* `ACCOUNT_HOLDER`
* `JOINT_ACCOUNT_HOLDER`
This means a joint or non-primary account holder can set up autopay, not just the primary holder.
**3. A funded payment source**
**For `INTERNAL_TRANSFER`**, you need the `source_account_id` of a Synctera platform account. The owning customer must hold one of the three ownership relationships above with that account too.
**For `ACH`**, you need the `external_account_id` of a linked external account. The external account must be verified and must be owned by the same customer, and you must have the customer's authorization to originate an outgoing ACH debit. See [External Accounts](/v2/docs/external-accounts-guide).
**4. Statements enabled (for STATEMENT autopays)**
`STATEMENT` autopays are triggered when a statement is generated for the billing cycle. The account must be producing statements with a minimum payment due and a payment due date. See [Statements](/v2/docs/statements-guide).
**5. API credentials**
A valid API key for the Sandbox or Production environment. See [Dev Setup](/v2/docs/dev-setup).
## Key concepts
### Autopay type
`autopay_type` controls what triggers an autopay. It also constrains which amount and timing rules are valid.
| Type | Trigger | Constraints |
| - | - | - |
| `STATEMENT` | Once per billing cycle, when a statement is created | `timing_rule` must be `ON_DUE_DATE` or `DAYS_BEFORE_DUE` |
| `SCHEDULED` | A recurring cadence, evaluated during end-of-day orchestration | `amount_rule` must be `CURRENT_BALANCE` and `timing_rule` must be `DAILY` |
`STATEMENT` is the typical credit card or line of credit use case: pay the bill each cycle. `SCHEDULED` is a sweep: pay down whatever is outstanding, every day.
### Amount rules
`amount_rule` determines how much each payment is for.
| Amount rule | Pays | Rule config |
| - | - | - |
| `MINIMUM_DUE` | The minimum payment due on the current statement | `minimum_due` (no fields) |
| `STATEMENT_BALANCE` | The full statement balance | `statement_balance` (no fields) |
| `CURRENT_BALANCE` | The current outstanding balance at execution time | `current_balance` (no fields) |
| `FIXED_AMOUNT` | A fixed amount, in cents | `fixed_amount.amount` (required) |
> [!NOTE]
>
> `FIXED_AMOUNT` never overpays. Synctera pays the lesser of the fixed amount and the current balance.
If the calculated amount is `0` — the balance is already paid off, for example — the autopay is skipped rather than executed, and its status becomes `SKIPPED`.
### Timing rules
`timing_rule` determines when the payment is initiated.
| Timing rule | Behavior | Rule config |
| - | - | - |
| `ON_DUE_DATE` | Initiate on the payment due date | — |
| `DAYS_BEFORE_DUE` | Initiate a set number of days before the due date | `days_before_due.offset_days` (required, 1–30) |
| `DAILY` | Evaluate every day (`SCHEDULED` autopays only) | — |
> [!WARNING]
>
> **ACH needs lead time.** An outgoing ACH debit takes one to three business days to settle, so `ON_DUE_DATE` combined with `ACH` risks a late payment. For ACH payment sources, use `DAYS_BEFORE_DUE` with an `offset_days` of 3 to 5.
### Payment method
`payment_method` determines how funds are moved, and which sub-object of `payment_configs` you must populate.
| Payment method | Mechanism | Payment config | Required field |
| - | - | - | - |
| `INTERNAL_TRANSFER` | Internal transfer from a Synctera platform account. Posts instantly. | `internal_transfer` | `source_account_id` |
| `ACH` | Outgoing ACH debit pulled from an external bank account. | `ach` | `external_account_id` |
The `ach` config also accepts two optional fields:
* `sec_code` — Standard Entry Class code: `WEB` (default), `CCD`, or `PPD`
* `is_same_day` — send as same-day ACH; defaults to `false`
The `internal_transfer` config accepts an optional `subtype` that sets the transaction subtype; it defaults to `auto_payment`.
### Rule configs and payment configs
`rule_configs` and `payment_configs` are containers holding rule-specific and method-specific settings. You only populate the sub-object that matches the rule or method you selected.
For example, an autopay using `DAYS_BEFORE_DUE` and `ACH` populates `rule_configs.days_before_due` and `payment_configs.ach`, and leaves the rest out. An autopay using `STATEMENT_BALANCE` and `ON_DUE_DATE` may omit `rule_configs` entirely, since neither rule takes parameters.
### Description template
`description_template` is an optional Go template that produces the ACH addenda record or the internal transfer memo. It supports these variables:
| Variable | Value |
| - | - |
| `{{.Last4AccountId}}` | Last 4 characters of the lending account UUID |
| `{{.BillingPeriodEndDate}}` | End date of the billing period, `YYYY-MM-DD` |
| `{{.PaymentAmount}}` | Payment amount formatted as currency, for example `$50.00` |
The template is rendered when the autopay record is created and stored on that record as `rendered_description`. The default is `Autopay`.
### Failure policy
`failure_policy` is required, and currently accepts a single value: `NO_RETRY`. A failed payment is not retried automatically. Configurable retry policies are planned but not yet available.
> [!WARNING]
>
> There are no autopay-specific webhook events today. To detect a failed payment, poll [`GET /v2/autopays`](/v2/reference/listautopays) filtered by `status=FAILED`, and inspect `attempt_history` for the reason.
### Statuses
An **autopay configuration** has a `status`:
| Status | Meaning |
| - | - |
| `ACTIVE` | The rule is in effect; new autopays will be created |
| `PAUSED` | Temporarily suspended; no new autopays are created |
| `DISABLED` | Turned off |
An **autopay** record has its own `status`:
| Status | Meaning |
| - | - |
| `PENDING` | Scheduled, waiting to execute |
| `EXECUTED` | Payment was initiated successfully |
| `SKIPPED` | Skipped — nothing owed, or cancelled by you |
| `FAILED` | Execution failed |
### Amounts on an autopay record
Two fields carry the amount, and they mean different things:
* `current_amount` — for a `PENDING` autopay, the **projected** amount, recomputed on every read from the config snapshot and current balances. It changes as the customer makes payments, receives refunds, or adds charges. For an `EXECUTED` autopay it mirrors `executed_amount`. For `SKIPPED` or `FAILED` autopays with no execution it is `0`.
* `executed_amount` — the amount actually used at execution. Absent until the autopay executes; once set, it is the source of truth and never changes.
> [!NOTE]
>
> Because `current_amount` is recalculated on read, it is what you should display in your UI for an upcoming payment — alongside a note such as "This amount may change if you make payments or receive refunds before the scheduled date."
### Config snapshot and attempt history
Each autopay record carries a `config_snapshot` — a copy of the configuration as it stood when the record was created. Editing the configuration later does not retroactively change an already-created autopay.
`attempt_history.attempts` lists each execution attempt chronologically, with `attempted_at`, a `status` of `SUCCESS`, `FAILED`, or `SKIPPED`, an optional `reason`, and `payment_attributes` identifying the resulting payment (`transaction_id` for an internal transfer, `ach_id` for an ACH debit).
## API workflow
**1. Create the autopay configuration**
`POST /v2/autopay_configs` creates the rule. Only one active configuration can exist per lending account; a second attempt returns `409`.
This example pays the full statement balance three days before the due date, from the customer's own deposit account on the platform.
```shell Shell theme={"system"}
curl \
-X POST \
https://api.synctera.com/v2/autopay_configs \
-H "Authorization: Bearer $apikey" \
-H 'Content-Type: application/json' \
-d '{
"lending_account_id": "7d943c51-e4ff-4e57-9558-08cab6b963c7",
"person_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"config": {
"autopay_type": "STATEMENT",
"amount_rule": "STATEMENT_BALANCE",
"timing_rule": "DAYS_BEFORE_DUE",
"rule_configs": {
"days_before_due": {
"offset_days": 3
}
},
"payment_method": "INTERNAL_TRANSFER",
"payment_configs": {
"internal_transfer": {
"source_account_id": "8f5b4c62-f5a0-4e68-9669-19dbc7a74d8e"
}
},
"failure_policy": "NO_RETRY",
"description_template": "Autopay for account ending in {{.Last4AccountId}}"
}
}'
```
A `201` response returns the configuration with its `id` and a `status` of `ACTIVE`:
```json JSON theme={"system"}
{
"id": "2d0f7601-ecc6-48b4-b82f-5d64fa84628b",
"lending_account_id": "7d943c51-e4ff-4e57-9558-08cab6b963c7",
"person_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "ACTIVE",
"config": {
"autopay_type": "STATEMENT",
"amount_rule": "STATEMENT_BALANCE",
"timing_rule": "DAYS_BEFORE_DUE",
"rule_configs": {
"days_before_due": { "offset_days": 3 }
},
"payment_method": "INTERNAL_TRANSFER",
"payment_configs": {
"internal_transfer": {
"source_account_id": "8f5b4c62-f5a0-4e68-9669-19dbc7a74d8e"
}
},
"failure_policy": "NO_RETRY",
"description_template": "Autopay for account ending in {{.Last4AccountId}}"
},
"tenant": "abcd1234_ef567890",
"creation_time": "2024-01-15T10:30:00Z",
"last_updated_time": "2024-01-15T10:30:00Z"
}
```
To pay the minimum due from an external bank account instead, swap the payment method and give ACH enough lead time:
```json JSON theme={"system"}
{
"lending_account_id": "7d943c51-e4ff-4e57-9558-08cab6b963c7",
"person_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"config": {
"autopay_type": "STATEMENT",
"amount_rule": "MINIMUM_DUE",
"timing_rule": "DAYS_BEFORE_DUE",
"rule_configs": {
"days_before_due": { "offset_days": 5 }
},
"payment_method": "ACH",
"payment_configs": {
"ach": {
"external_account_id": "8f5b4c62-f5a0-4e68-9669-19dbc7a74d8e",
"sec_code": "WEB",
"is_same_day": false
}
},
"failure_policy": "NO_RETRY"
}
}
```
**2. Let Synctera create the autopay records**
You do not create autopays. For a `STATEMENT` configuration, when a statement is generated Synctera creates an autopay with:
* `scheduled_date` — the due date, minus `offset_days` if you used `DAYS_BEFORE_DUE`
* `status` — `PENDING`
* `config_snapshot` — a copy of the rule as it stands now
* `statement_id` and `billing_period_id` — the statement this autopay pays
* `rendered_description` — your description template, rendered
For a `SCHEDULED` configuration, autopays are created during end-of-day orchestration and have no `billing_period_id`.
**3. Show the customer their upcoming payment**
List autopays for the account with [`GET /v2/autopays`](/v2/reference/listautopays), or fetch one with [`GET /v2/autopays/{autopay_id}`](/v2/reference/getautopay).
```shell Shell theme={"system"}
curl \
-X GET \
"https://api.synctera.com/v2/autopays?lending_account_id=7d943c51-e4ff-4e57-9558-08cab6b963c7&status=PENDING" \
-H "Authorization: Bearer $apikey"
```
```json JSON theme={"system"}
{
"autopays": [
{
"id": "2d0f7601-ecc6-48b4-b82f-5d64fa84628b",
"autopay_config_id": "3e1f8712-fdd7-59c5-c93f-6e75fb95739c",
"autopay_type": "STATEMENT",
"lending_account_id": "7d943c51-e4ff-4e57-9558-08cab6b963c7",
"statement_id": "5g3h0934-hff9-71e7-e15h-8g97hd17951e",
"scheduled_date": "2024-03-19",
"status": "PENDING",
"current_amount": 48723,
"rendered_description": "Autopay for account ending in 1234",
"creation_time": "2024-03-01T10:30:00Z",
"last_updated_time": "2024-03-01T10:30:00Z"
}
]
}
```
Useful filters include `lending_account_id`, `autopay_config_id`, `status`, `statement_id`, `billing_period_id`, `scheduled_date` (or the `from_scheduled_date` / `to_scheduled_date` range), and `from_executed_amount` / `to_executed_amount`.
**4. Check the outcome after execution**
On the scheduled date Synctera recomputes the amount and acts:
* Amount greater than `0` and payment succeeds → `status` becomes `EXECUTED`, `executed_amount` is set, and `payment_attributes` carries the `transaction_id` or `ach_id`
* Amount is `0` → `status` becomes `SKIPPED`
* Payment fails → `status` becomes `FAILED`, and `attempt_history` records the reason
Poll [`GET /v2/autopays`](/v2/reference/listautopays) with `status=FAILED` to find payments that need attention. Because the only failure policy today is `NO_RETRY`, a failed autopay is not retried — the customer must make a manual payment.
**5. Cancel a single upcoming payment**
To skip one scheduled payment without touching the underlying rule, use [`PATCH /v2/autopays/{autopay_id}`](/v2/reference/patchautopay) to set its status to `SKIPPED`. This is the only update the endpoint supports, and it only applies to a `PENDING` autopay.
```shell Shell theme={"system"}
curl \
-X PATCH \
https://api.synctera.com/v2/autopays/2d0f7601-ecc6-48b4-b82f-5d64fa84628b \
-H "Authorization: Bearer $apikey" \
-H 'Content-Type: application/json' \
-d '{ "status": "SKIPPED" }'
```
> [!WARNING]
>
> Cancel before the payment is initiated. If the ACH debit has already gone out, cancelling the autopay record does not recall it — that payment will post as scheduled. Tell the customer that cancelling applies to payments not yet initiated.
**6. Update or pause the configuration**
[`PATCH /v2/autopay_configs/{autopay_config_id}`](/v2/reference/updateautopayconfig) updates the `config`, the `status`, or both — for example to change the payment source, switch the amount rule, or pause autopay.
```shell Shell theme={"system"}
curl \
-X PATCH \
https://api.synctera.com/v2/autopay_configs/2d0f7601-ecc6-48b4-b82f-5d64fa84628b \
-H "Authorization: Bearer $apikey" \
-H 'Content-Type: application/json' \
-d '{ "status": "PAUSED" }'
```
Because each autopay record holds a `config_snapshot`, an edit does not change an autopay that has already been created. If a payment for the current cycle has already been initiated, the edit takes effect starting with the next cycle — surface that to the customer rather than letting them assume this month's payment changed.
**7. Delete the configuration**
[`DELETE /v2/autopay_configs/{autopay_config_id}`](/v2/reference/deleteautopayconfig) removes the rule and returns `204`. Use this when the customer turns autopay off for good; use `PAUSED` when they may turn it back on.
> [!NOTE]
>
> An account relationship cannot be deleted while an active autopay configuration depends on it. Delete or repoint the autopay configuration first.
## Validation rules
The API rejects a configuration with `400` when these constraints are not met:
| Constraint | Detail |
| - | - |
| Exactly one customer | Provide `person_id` or `business_id`, never both and never neither |
| Ownership | The customer must hold `PRIMARY_ACCOUNT_HOLDER`, `ACCOUNT_HOLDER`, or `JOINT_ACCOUNT_HOLDER` on the lending account, and on the internal source account if one is used |
| `SCHEDULED` pairing | Requires `amount_rule` of `CURRENT_BALANCE` and `timing_rule` of `DAILY` |
| `STATEMENT` pairing | Requires `timing_rule` of `ON_DUE_DATE` or `DAYS_BEFORE_DUE` |
| `DAYS_BEFORE_DUE` | Requires `rule_configs.days_before_due.offset_days`, between 1 and 30 |
| `FIXED_AMOUNT` | Requires `rule_configs.fixed_amount.amount`, in cents |
| `ACH` | Requires `payment_configs.ach.external_account_id`, verified and owned by the same customer |
| `INTERNAL_TRANSFER` | Requires `payment_configs.internal_transfer.source_account_id` |
| One per account | A second active configuration on the same lending account returns `409` |
## Things to watch for
**Avoid double payments.** If a payment has been initiated but has not yet posted, a second payment can overdraw the customer. Check for a `PENDING` or recently `EXECUTED` autopay before initiating a manual payment for the same cycle.
**ACH settles on its own schedule.** An outgoing ACH debit is initiated on the scheduled date but posts one to three business days later. The balance and any days-past-due calculation only change on the posting date. Build in lead time with `offset_days` rather than relying on the due date.
**The projected amount moves.** `current_amount` on a `PENDING` autopay is recomputed on every read. A manual payment or a posted refund lowers it; new charges can raise it when the rule is `CURRENT_BALANCE`. Read it fresh rather than caching it.
**Failures are terminal for that cycle.** With `NO_RETRY` as the only failure policy, a failed autopay stays failed. Detect it by polling and prompt the customer to pay manually or fix their payment source.
## Reference
| Operation | Endpoint |
| - | - |
| Create autopay configuration | [`POST /v2/autopay_configs`](/v2/reference/createautopayconfig) |
| List autopay configurations | [`GET /v2/autopay_configs`](/v2/reference/listautopayconfigs) |
| Get autopay configuration | [`GET /v2/autopay_configs/{autopay_config_id}`](/v2/reference/getautopayconfig) |
| Update autopay configuration | [`PATCH /v2/autopay_configs/{autopay_config_id}`](/v2/reference/updateautopayconfig) |
| Delete autopay configuration | [`DELETE /v2/autopay_configs/{autopay_config_id}`](/v2/reference/deleteautopayconfig) |
| List autopays | [`GET /v2/autopays`](/v2/reference/listautopays) |
| Get autopay | [`GET /v2/autopays/{autopay_id}`](/v2/reference/getautopay) |
| Update autopay | [`PATCH /v2/autopays/{autopay_id}`](/v2/reference/patchautopay) |
# Balance Floor and Ceiling and Linked Accounts
Source: https://docs.synctera.com/v2/docs/balance-floor-ceiling
Accounts can have a minimum and maximum balance, referred to as the balance floor and balance ceiling. These attributes can be used to implement a number of features, including pool accounts.
Balance Floor and Ceiling can be set while creating an account using [`POST /v0/accounts`](/v2/reference/createaccount)
## Balance Floor
An account's balance floor consists of two attributes:
* `balance`: the minimum balance the account can have
* `linked_account_id`: the ID of the linked account used to maintain the minimum balance
The balance floor creates a lower limit for the available balance of that account. Any transaction that would put the available balance of the account below its balance floor triggers a just-in-time (JIT) funding transaction from the linked account in order to bring the balance back up to the floor.
## Balance Ceiling
The balance ceiling creates an upper limit for the available balance. Any transaction that would put the available balance of the account above its balance ceiling triggers a just-in-time (JIT) funding transaction (also known as a sweep transaction) to the linked account in order to bring the balance back down to the ceiling.
## Example Use Cases
### Pool Account
There are a number of use cases where you want an account that always has a zero balance, and gets its funds from another account. For example, you many have a single pool account containing the funds for multiple business expense cards. In this case, each card's account would be set up like:
```json JSON theme={"system"}
balance_floor: {
"balance": 0,
"linked_account_id": "{POOL_ACCOUNT_ID}"
}
balance_ceiling: {
"balance": 0,
"linked_account_id": "{POOL_ACCOUNT_ID}"
}
```
All credits and debits to any of the card accounts would flow through to the pool account. Refer to the [Business Expense Cards](/v2/docs/business-card) for more details.
# Bank Migration Guide
Source: https://docs.synctera.com/v2/docs/bank-migration
Use the Migration Mapping API to link old and new resources when migrating from one sponsor bank to another on the Synctera platform.
When a FinTech migrates from one sponsor bank to another on the Synctera platform, resources such as customers, accounts, and external accounts must be recreated under the new bank's tenant. The **Migration Mapping API** provides a persistent record of the relationship between an old resource and its newly created counterpart, bridging the two tenants throughout the migration and afterward.
Migration mappings do not move data or trigger any automated migration process. They serve two key purposes:
* **Operational continuity** — FinTech operators, Synctera support teams, and bank partners can navigate between old and new records in the Synctera dashboard during and after a migration.
* **Behind-the-scenes integrations** — Synctera uses mappings internally to coordinate activities that require knowledge of both the old and new resource, such as transferring a credit-reporting tradeline from the old bank to the new one without disrupting the customer's credit history.
## Prerequisites
Before using the Migration Mapping API you should be familiar with:
* [Create a Personal Customer](/v2/docs/create-a-personal-customer)
* [Create a Business Customer](/v2/docs/create-a-business)
* Accounts — creating deposit and other account types
You will need:
* An API key for your **existing** (old) tenant
* An API key for your **new** tenant
* The resource IDs of records you intend to migrate (customers, accounts, etc.)
## The migration mapping object
A migration mapping represents the link between one specific resource on the old tenant and its newly created equivalent on the new tenant.
```json theme={"system"}
{
"id": "191edb33-3fca-4c68-8ca5-871fa0d5e3f5",
"tenant": "456",
"resource_id": "def45678-0000-0000-0000-000000000002",
"old_tenant": "123",
"old_resource_id": "abc12345-0000-0000-0000-000000000001",
"resource_type": "PERSON",
"creation_time": "2026-03-01T10:00:00Z",
"last_updated_time": "2026-03-01T10:00:00Z"
}
```
| Field | Description |
| - | - |
| `id` | Unique identifier for the migration mapping |
| `tenant` | Tenant ID of the **new** bank |
| `resource_id` | ID of the resource in the **new** tenant |
| `old_tenant` | Tenant ID of the **old** bank |
| `old_resource_id` | ID of the resource in the **old** tenant |
| `resource_type` | The type of resource being mapped. One of `PERSON`, `BUSINESS`, or `ACCOUNT` |
| `creation_time` | ISO 8601 timestamp when this mapping was created |
| `last_updated_time` | ISO 8601 timestamp when this mapping was last updated |
### Copying SSNs with `allow_ssn_copy`
`allow_ssn_copy` is an optional request field on create. It is not part of the stored mapping object.
| Field | Type | Default | Description |
| - | - | - | - |
| `allow_ssn_copy` | boolean | `false` | When `true`, Synctera copies the vaulted SSN from the customer at `old_resource_id` to the customer at `resource_id` when the mapping is created. Applies to `PERSON` mappings. |
Because copying an SSN between customer records is sensitive, Synctera verifies that the names on the old and new customers match before copying. A mismatch is rejected with an error, which prevents a wrong or malicious mapping from attaching one person's SSN to a different customer.
### Cross-tenant access
Migration mappings are stored under the new tenant (`tenant`) but are queryable using an API key from either the old or the new tenant. This allows operators to look up a mapping regardless of which API key they have at hand during the migration process.
### Permissions
Querying and managing migration mappings uses the same permissions as the underlying resource type:
| `resource_type` | Required permission |
| - | - |
| `PERSON` | `customer:read` / `customer:write` |
| `BUSINESS` | `customer:read` / `customer:write` |
| `ACCOUNT` | `account:read` / `account:write` |
## Example: Migrate customers and accounts to a new bank
The following example walks through the complete workflow for migrating personal customers and their associated accounts from an old tenant to a new tenant.
**1. Fetch customers from the old tenant**
Start by retrieving the list of customers to be migrated from your existing tenant. In this example, the old tenant ID is `123` and the new tenant ID is `456`.
```shell theme={"system"}
curl -X GET https://api.synctera.com/v2/persons \
-H "Authorization: Bearer $old_apikey"
```
The response returns a paginated list of person objects. Record the `id` of each person you intend to migrate.
```json theme={"system"}
{
"persons": [
{
"id": "abc12345-0000-0000-0000-000000000001",
"first_name": "Jane",
"last_name": "Smith",
"email": "jane.smith@example.com"
}
],
"next_page_token": "..."
}
```
**2. Fetch accounts for each customer**
For each customer, retrieve their accounts so you have the full picture of what needs to be recreated.
```shell theme={"system"}
curl -X GET "https://api.synctera.com/v2/accounts?customer_id=abc12345-0000-0000-0000-000000000001" \
-H "Authorization: Bearer $old_apikey"
```
Record the `id` of each account alongside its owner's person ID.
**3. Recreate customers on the new tenant**
Using the information collected above, create each customer on the new tenant. Submit the same personal information as was on record under the old tenant. If you don't have access to customers' SSNs, omit `ssn` here and set `allow_ssn_copy` when you create the migration mapping (see below).
```shell theme={"system"}
curl -X POST https://api.synctera.com/v2/persons \
-H "Authorization: Bearer $new_apikey" \
-H "Content-Type: application/json" \
--data-binary '{
"first_name": "Jane",
"last_name": "Smith",
"dob": "1985-06-15",
"email": "jane.smith@example.com",
"phone_number": "+14155551234",
"legal_address": {
"street_line_1": "123 Main St",
"city": "San Francisco",
"state": "CA",
"postal_code": "94105",
"country_code": "US"
}
}'
```
The response includes the new `id` for the person on the new tenant. Record this value — you will need it when creating the migration mapping.
```json theme={"system"}
{
"id": "def45678-0000-0000-0000-000000000002",
"first_name": "Jane",
"last_name": "Smith"
}
```
Repeat this step for each customer in your migration list, keeping a record of the mapping from old IDs to new IDs.
**4. Recreate accounts on the new tenant**
With the new customer IDs in hand, create corresponding accounts on the new tenant. Use the same account configuration (product type, etc.) as the original.
```shell theme={"system"}
curl -X POST https://api.synctera.com/v2/accounts \
-H "Authorization: Bearer $new_apikey" \
-H "Content-Type: application/json" \
--data-binary '{
"account_type": "CHECKING",
"customer_ids": ["def45678-0000-0000-0000-000000000002"]
}'
```
Record the new account `id` returned in the response alongside the old account `id`.
**5. Create migration mappings for customers**
Now that each customer exists on both tenants, create a migration mapping for each person. This call can be made with either the old or the new API key.
```shell theme={"system"}
curl -X POST https://api.synctera.com/v2/migration_mappings \
-H "Authorization: Bearer $new_apikey" \
-H "Content-Type: application/json" \
--data-binary '{
"tenant": "456",
"resource_id": "def45678-0000-0000-0000-000000000002",
"old_tenant": "123",
"old_resource_id": "abc12345-0000-0000-0000-000000000001",
"resource_type": "PERSON"
}'
```
A successful response returns the complete migration mapping object:
```json theme={"system"}
{
"id": "191edb33-3fca-4c68-8ca5-871fa0d5e3f5",
"tenant": "456",
"resource_id": "def45678-0000-0000-0000-000000000002",
"old_tenant": "123",
"old_resource_id": "abc12345-0000-0000-0000-000000000001",
"resource_type": "PERSON",
"creation_time": "2026-03-01T10:00:00Z",
"last_updated_time": "2026-03-01T10:00:00Z"
}
```
> [!NOTE]
>
> **Carrying over SSNs.** A customer's SSN is a vaulted value, so you can't read it from the old tenant and re-submit it unless you have been granted access to reveal it. To have Synctera copy it for you, set `allow_ssn_copy` to `true` when creating a `PERSON` mapping. The SSN is copied directly from the old customer to the new customer. It is never returned in the API response.
>
> ```shell theme={"system"}
> curl -X POST https://api.synctera.com/v2/migration_mappings \
> -H "Authorization: Bearer $new_apikey" \
> -H "Content-Type: application/json" \
> --data-binary '{
> "tenant": "456",
> "resource_id": "def45678-0000-0000-0000-000000000002",
> "old_tenant": "123",
> "old_resource_id": "abc12345-0000-0000-0000-000000000001",
> "resource_type": "PERSON",
> "allow_ssn_copy": true
> }'
> ```
>
> As a safeguard, Synctera compares the names on the old and new customers before copying. If they don't match, the request is rejected with an error and no SSN is copied. Create the new customer with the same name as on record in the old tenant.
Repeat this step for each migrated customer.
**6. Create migration mappings for accounts**
Create a corresponding mapping for each account, linking the old account ID to the new account ID.
```shell theme={"system"}
curl -X POST https://api.synctera.com/v2/migration_mappings \
-H "Authorization: Bearer $new_apikey" \
-H "Content-Type: application/json" \
--data-binary '{
"tenant": "456",
"resource_id": "acct9999-0000-0000-0000-000000000004",
"old_tenant": "123",
"old_resource_id": "acct1111-0000-0000-0000-000000000003",
"resource_type": "ACCOUNT"
}'
```
You have now recreated your customers and accounts on the new tenant and established a persistent record linking each pair of old and new resources. Synctera will use these mappings to automatically coordinate any downstream processes that require knowledge of both records, such as transferring credit-reporting tradelines.
## Querying migration mappings
You can look up migration mappings at any time using any combination of the following filters.
### Look up by resource ID
The `resource_id` filter matches against **both** `resource_id` and `old_resource_id`. Use it whenever you have an ID and don't need to constrain which side of the mapping it belongs to — this is the most common lookup pattern.
```shell theme={"system"}
curl -X GET "https://api.synctera.com/v2/migration_mappings?resource_type=PERSON&resource_id=def45678-0000-0000-0000-000000000002" \
-H "Authorization: Bearer $new_apikey"
```
### Look up strictly by the old resource ID
If you specifically want to match only on the old side of the mapping (for example, to find every record that originated from a particular old resource), use `old_resource_id`.
```shell theme={"system"}
curl -X GET "https://api.synctera.com/v2/migration_mappings?resource_type=PERSON&old_resource_id=abc12345-0000-0000-0000-000000000001" \
-H "Authorization: Bearer $old_apikey"
```
## Updating and deleting mappings
### Update a mapping
Use `PATCH` to update mutable fields on an existing mapping (for example, if a resource ID was recorded incorrectly).
```shell theme={"system"}
curl -X PATCH https://api.synctera.com/v2/migration_mappings/191edb33-3fca-4c68-8ca5-871fa0d5e3f5 \
-H "Authorization: Bearer $new_apikey" \
-H "Content-Type: application/json" \
--data-binary '{
"resource_id": "def99999-0000-0000-0000-000000000002"
}'
```
### Delete a mapping
```shell theme={"system"}
curl -X DELETE https://api.synctera.com/v2/migration_mappings/191edb33-3fca-4c68-8ca5-871fa0d5e3f5 \
-H "Authorization: Bearer $new_apikey"
```
> [!WARNING]
>
> Deleting a migration mapping removes the link between the old and new resource. Synctera will no longer be able to automatically coordinate downstream processes (such as credit-reporting tradeline transfers) for the affected resource. Only delete a mapping if you are certain the association is no longer needed.
## Webhooks
Synctera publishes webhook events for migration mapping lifecycle changes. Subscribe to these events to trigger your own automation during a migration.
| Event | Description |
| - | - |
| `RESOURCE_MAPPING.CREATED` | A new migration mapping was created |
| `RESOURCE_MAPPING.UPDATED` | An existing mapping was updated |
| `RESOURCE_MAPPING.DELETED` | A mapping was deleted |
See the [Webhooks guide](/v2/docs/webhooks-guide) for instructions on configuring webhook subscriptions.
## Related guides
> [card] [Create a Personal Customer](/v2/docs/create-a-personal-customer)
>
> Recreate personal customers on the new tenant.
> [card] [Create a Business Customer](/v2/docs/create-a-business)
>
> Recreate business customers on the new tenant.
> [card] [Create Accounts](/v2/docs/create-accounts-guide)
>
> Recreate accounts before mapping old and new IDs.
> [card] [Webhooks](/v2/docs/webhooks-guide)
>
> Subscribe to migration mapping lifecycle events.
## API reference
See the full Migration Mappings API reference for request/response schemas and all available parameters:
* [List migration mappings](/v2/reference/listmigrationmappings)
* [Create a migration mapping](/v2/reference/createmigrationmapping)
* [Get a migration mapping](/v2/reference/getmigrationmapping)
* [Update a migration mapping](/v2/reference/updatemigrationmapping)
* [Delete a migration mapping](/v2/reference/deletemigrationmapping)
## Navigating migrated resources in the dashboard
Once migration mappings exist, the Synctera dashboard surfaces links between old and new records. On any customer or account detail page, an action menu item — **View Migrated Resource** — will appear when a mapping exists. Selecting it navigates directly to the corresponding record on the other tenant, making it easy for FinTech operators, bank partners, and Synctera support to trace a resource through the migration.
## What happens after mappings are created
After you create migration mappings for your customers and accounts, Synctera uses the mappings to handle certain processes automatically on your behalf. You do not need to take additional action for these:
* **Credit-reporting tradeline transfer** — For FinTechs that report to credit bureaus, Synctera will record a sale of the tradeline on the old bank and a corresponding purchase on the new bank, ensuring your customers' credit histories remain uninterrupted.
* **SSN copy** — If you set `allow_ssn_copy` on a customer mapping, Synctera copies the vaulted SSN to the new customer at mapping creation, so you don't need to re-submit it.
Other post-migration steps — such as re-running KYC, issuing new cards, and migrating balances — must be completed by your team as part of your broader migration runbook. Work with your Synctera implementation manager for a full migration checklist.
# Build Overview
Source: https://docs.synctera.com/v2/docs/build-card-program
End-to-end setup paths for each card product Synctera supports, from customer creation through to an active card in your customer's hands.
Every card program follows the same shape: create and verify a customer, record disclosures, create the account the card spends against, then issue and activate the card. What changes between products is the account type, whether an application and credit decision are involved, and which disclosures are required.
Pick your product below. If you have not yet decided, start with [Design Your Card Program](/v2/docs/card-programs).
## At a glance
| Product | Card type | Account type | Application required |
| - | - | - | - |
| [Debit Card](/v2/docs/build-debit-card) | `DEBIT` | `CHECKING` | No |
| [Prepaid Card](/v2/docs/build-prepaid-card) | `PREPAID` | `PREPAID` | No |
| [Secured Smart Card](/v2/docs/build-smart-card) | `CREDIT` | `CHARGE_SECURED` + deposit account | Optional |
| [Unsecured Charge Card](/v2/docs/build-charge-card) | `CREDIT` | `CHARGE_UNSECURED` | Yes |
| [Revolving Credit Card](/v2/docs/build-revolving-credit-card) | `CREDIT` | `CREDIT_CARD` | Yes |
> [!NOTE]
>
> Credit, charge, and revolving products require specific privileges on your organization. Contact your Synctera representative before planning one.
# Unsecured Charge Card
Source: https://docs.synctera.com/v2/docs/build-charge-card
A credit line with no collateral, repaid in full each billing cycle. Underwriting decides who gets one and how much they get.
An unsecured charge card extends credit against nothing but the cardholder's creditworthiness. There is no deposit backing it and no collateral to fall back on, so the product turns on underwriting: someone has to decide whether to lend and how much.
Because the balance is repaid in full each cycle and never carries, no interest accrues. Revenue comes from interchange and fees rather than finance charges.
## Overview
### Key Concepts
> [accordion] Unsecured credit and the credit limit
>
> Nothing secures the line, so the credit limit is the output of a credit decision rather than of what the customer holds. It is set on the account as `credit_limit`, in cents.
>
> Available credit is the limit minus the current balance: it falls as the cardholder spends and recovers when they repay.
>
> This is the main difference from the [Secured Smart Card](/v2/docs/build-smart-card), where spending power comes from the customer's own deposits and no credit decision is made.
> [accordion] Charge, not revolving
>
> The full balance is due each cycle. In the API this is not a policy you enforce yourself — it is the account's `minimum_payment` scheme, and for a charge account the only supported value is `FULL`.
>
> A revolving account supports `RATE_OR_AMOUNT` as well, which is what allows a balance to be carried and interest to accrue. Choosing the account type chooses the repayment behaviour. See [Revolving Credit Card](/v2/docs/build-revolving-credit-card).
> [accordion] Billing cycle and grace period
>
> `billing_period` sets the frequency and the day each cycle anchors to. Monthly is the common choice, and a monthly cycle must start between the 1st and the 28th so that every month contains the start day.
>
> `grace_period` is how many days past the end of the cycle the customer has before payment is considered overdue, and it determines the due date. It is required on the account template.
### How It Differs from Other Cards
| | Unsecured Charge | Secured Smart Card | Revolving Credit | Debit |
| - | - | - | - | - |
| Backed by | Nothing — the credit line is unsecured | The customer's own deposits | A credit line | The deposit account itself |
| Underwriting | Required | None | Depends on bank agreement | None |
| Application | **Required** | Optional | Required | None |
| Carrying a balance | Not allowed | Not allowed | Allowed | Not applicable |
| Minimum payment scheme | `FULL` only | `FULL` only | `FULL` or `RATE_OR_AMOUNT` | Not applicable |
| Interest | None | None | On carried balances | None |
| Account type | `CHARGE_UNSECURED` | `CHARGE_SECURED` | `CREDIT_CARD` | `CHECKING` |
Charge cards can be issued to consumers or businesses.
### Who Decides What
| Responsibility | Who |
| - | - |
| **Credit decision and limit** | Underwriting — depends on program structure agreed between you and your sponsor bank. |
| **Capital** | Whoever funds the receivable: you, a debt provider, or your sponsor bank. |
| **Authorization** | Synctera, against available credit, account standing, spend controls, and fraud rules. |
| **Repayment** | The customer, in full each cycle. |
| **Adverse action notices** | You, within the regulatory deadline, using the records Synctera holds. |
| **Collections** | Typically you, or a servicer you appoint. |
## API Flow
An unsecured charge account cannot exist without an approved application, so the application is the spine of this flow rather than an optional step.
```mermaid mermaid theme={"system"}
%%{init: {"fontFamily": "sans-serif"}}%%
flowchart TB
A["Create and verify the customer"] --> B["Record disclosures"]
B --> C["Create the application"]
C --> D{"Credit decision"}
D -->|Approved| E["Create the account
with application_id and credit_limit"]
D -->|Declined| F["Record an adverse action"]
E --> G["Issue the card"]
```
The `curl` examples assume you have set up `baseurl` and `apikey` environment variables. See [Base URL](/v2/reference/environments) and [Authentication](/v2/reference/authentication).
### Step 1 — Create and Verify the Customer
Create the person or business and complete KYC or KYB. See [Create a Personal Customer](/v2/docs/create-a-personal-customer), [Create a Business](/v2/docs/create-a-business), and [KYC/KYB Verification](/v2/docs/kyc-kyb-verification).
### Step 2 — Record Disclosures
Record the customer's acknowledgement of each required disclosure. See [Record Disclosure Acceptance](/v2/docs/record-disclosure-acceptance).
### Step 3 — Create the Application
The customer applies through the Application API. This is required — without an approved application there is no `application_id`, and without that the account cannot be created.
See [Credit Applications](/v2/docs/credit-applications-guide).
### Step 4 — Record the Credit Decision
Underwriting depends on program structure agreed between you and your sponsor bank.
The application must be approved and accepted by the applicant before the account can be created.
### Step 5 — Handle a Declined Application
A declined applicant must receive an adverse action notice. Under Regulation B and the FCRA it has to reach them within 30 days of the decision and state the specific reasons for denial, along with the required ECOA and enforcement agency language.
Create the record with [Create Adverse Action](/v2/reference/createadverseaction), then mark the application `CREDIT_DENIED` with the adverse action ID attached. Required for personal customers, optional for business customers.
See [Adverse Actions](/v2/docs/adverse-actions-guide).
### Step 6 — Create the Account
Create the `CHARGE_UNSECURED` account, passing the approved application and the credit limit.
```shell Shell theme={"system"}
curl -X POST "$baseurl/v2/accounts" \
-H "Authorization: Bearer $apikey" \
-H 'Content-Type: application/json' \
--data-binary '{
"account_template_id": "{ACCOUNT_TEMPLATE_ID}",
"account_purpose": "Charge Card Account",
"application_id": "{APPLICATION_ID}",
"credit_limit": 100000,
"relationships": [
{
"relationship_type": "PRIMARY_ACCOUNT_HOLDER",
"customer_id": "{CUSTOMER_ID}"
}
]
}'
```
`credit_limit` is in cents, so the value above is a \$1,000 limit. The template supplies the billing period, grace period, and minimum payment scheme.
See [Unsecured Charge Accounts](/v2/docs/unsecured-charge-accounts-guide).
We refer to the resulting account's UUID as `{ACCOUNT_ID}`.
### Step 7 — Issue the Card
Issue against the charge account with `"type": "CREDIT"`, using a card product on a BIN that supports credit. Physical and virtual cards are both supported.
```shell Shell theme={"system"}
curl -X POST "$baseurl/v2/cards" \
-H "Authorization: Bearer $apikey" \
-H 'Content-Type: application/json' \
--data-binary '{
"type": "CREDIT",
"card_details": {
"form": "VIRTUAL",
"account_id": "{ACCOUNT_ID}",
"customer_id": "{CUSTOMER_ID}",
"card_product_id": "{CARD_PRODUCT_ID}"
}
}'
```
See [Issue a Card](/v2/docs/issue-a-card).
## Running the Program
### Repayment
The full balance is due by the date the grace period sets. Because nothing carries, a missed payment is a delinquency rather than a rolled balance — there is no interest mechanism to absorb it.
### Statements
Synctera closes each billing cycle and generates a statement showing the transactions, the balance, and the due date. See [Statements](/v2/docs/statements-guide).
### Spend Controls
Spend controls limit spend by amount, window, payment type, and merchant category, and attach to the account. See [Spend Controls](/v2/docs/spend-controls-guide).
### Fees and Rewards
With no interest to earn, fees and interchange carry the economics. Configure fees and any rewards as rules bundled into products linked to the account template. See [Fees and Rewards](/v2/docs/fees-and-rewards).
### Disputes
Cardholders can dispute any card transaction. See [Card Transaction Disputes](/v2/docs/card-transaction-disputes).
### Delinquency and Collections
Your program configuration sets how long past the due date a card is suspended, when the customer is reported delinquent, and when the balance is charged off. Collections are typically your responsibility or a servicer's.
### Credit Bureau Reporting
Payment history on the account can be furnished to the credit bureaus. Furnishing requires bureau credentialing for your program, arranged with your Synctera representative.
# Debit Card
Source: https://docs.synctera.com/v2/docs/build-debit-card
A debit card spends directly from a customer's deposit account at the time of purchase. It is the simplest card program to run — no underwriting, no credit decision, no repayment.
A debit card is an access mechanism for money the customer already has. Each purchase draws against their deposit account balance, so there is no credit risk, no billing cycle, and no repayment to manage. That makes it the fastest card program to stand up and the usual starting point for consumer and neobank products.
## Overview
### Key Concepts
Three mechanisms determine how a debit program behaves day to day.
> [accordion] Funding and available balance
>
> The card is linked to a deposit account, and that account's balance is the card's spending power. Synctera tracks two balances:
>
> * **`ACCOUNT_BALANCE`** — the posted balance: credits minus debits across all posted transactions.
> * **`AVAILABLE_BALANCE`** — what can actually be spent: the account balance minus any pending debits, including holds placed by card authorizations that have not yet cleared.
>
> Authorizations are evaluated against the available balance, which is why a customer who just made a purchase sees less spending power than their posted balance suggests.
> [accordion] Authorization and settlement
>
> Card spend reaches you in two parts. At the moment of purchase the network sends a **funding request**, Synctera approves or declines it, and an approval places a hold against the available balance. You can also participate in the authorzation flow.
>
> Later the merchant submits the transaction for **clearing**, and the money actually moves. The cleared amount can differ from the authorized amount — a tip added after the card is swiped, or a fuel pump that authorizes a fixed amount and clears what was pumped. An authorization advice adjusts the hold in between; a reversal releases it entirely.
>
> ATM withdrawals and PIN debit purchases are **single-message**: authorized and cleared together, so funds move immediately.
>
> See [Card Transactions](/v2/docs/card-transactions).
> [accordion] PIN and card-present use
>
> A debit card needs a PIN for ATM withdrawals and for point-of-sale transactions where the merchant requests one. This applies to virtual cards too — a merchant terminal can ask for a PIN when the card is used through a digital wallet, and a card with no PIN set cannot complete that purchase.
### How It Differs from Other Card Types
| | Debit | Prepaid | Credit and charge |
| - | - | - | - |
| Funds come from | The customer's deposit account | A pre-loaded balance | A credit line |
| When money leaves the customer | At clearing | At clearing | At repayment |
| Underwriting | None | None | Required |
| Interest | None on card spend | None | On carried balances (revolving only) |
| Account types | `CHECKING` | `CHECKING` or `PREPAID` | `CHARGE_*`, `CREDIT_CARD` |
See [Prepaid Card](/v2/docs/build-prepaid-card), [Secured Smart Card](/v2/docs/build-smart-card), [Unsecured Charge Card](/v2/docs/build-charge-card), and [Revolving Credit Card](/v2/docs/build-revolving-credit-card).
### Who Decides What
| Responsibility | Who |
| - | - |
| **Authorization decisions** | Synctera, against available balance, account standing, spend controls, address verification, and fraud rules. You can join the auth flow and decide per transaction if you need to. |
| **Funding** | The customer, through deposits into their account. |
| **Spend limits** | You, through spend controls on the account or the card. |
| **Disputes** | You raise them; Synctera works the case with the network. |
## API Flow
This guide follows the virtual-first pattern Synctera recommends: the customer gets a virtual card the moment onboarding completes, and a physical card arrives a few days later.
The `curl` examples assume you have set up `baseurl` and `apikey` environment variables. See [Base URL](/v2/reference/environments) and [Authentication](/v2/reference/authentication). Identifiers produced by earlier steps are written like `{ACCOUNT_ID}`.
```mermaid mermaid theme={"system"}
%%{init: {"fontFamily": "sans-serif"}}%%
flowchart LR
P["Person
KYC ACCEPTED"] --> A["CHECKING account
is_card_enabled: true"]
A --> V["Virtual debit card
active immediately"]
A --> F["Physical debit card
activated on arrival"]
```
### Step 1 — Create and Verify the Customer
Create a personal customer and run KYC. The customer must reach a `verification_status` of `ACCEPTED` before they can hold an account or use a card.
See [Create a Personal Customer](/v2/docs/create-a-personal-customer) and [KYC/KYB Verification](/v2/docs/kyc-kyb-verification).
Record the disclosures your program requires as part of onboarding — typically the USA Patriot Act notice, E-Sign consent, the privacy notice, and your deposit account agreement. See [Record Disclosure Acceptance](/v2/docs/record-disclosure-acceptance).
We refer to the resulting person's UUID as `{CUSTOMER_ID}`.
### Step 2 — Create an Account Template
The template defines the shape of every checking account you open for this program. Cards must be enabled on it.
```shell Shell theme={"system"}
curl -X POST "$baseurl/v0/accounts/templates" \
-H "Authorization: Bearer $apikey" \
-H 'Content-Type: application/json' \
--data-binary '{
"name": "consumer debit checking",
"description": "Checking accounts backing consumer debit cards",
"is_enabled": true,
"template": {
"account_type": "CHECKING",
"bank_country": "US",
"currency": "USD",
"is_ach_enabled": true,
"is_card_enabled": true,
"is_p2p_enabled": true,
"overdraft_limit": 0
}
}'
```
Note the returned `id` — we refer to it as `{ACCOUNT_TEMPLATE_ID}`.
> [!TIP]
>
> You only build the template once, not once per customer. If you want every account in this program to carry the same spending limits or fee structure, attach a `spend_control_id` and a fee product to the template now — accounts inherit them at creation. See [Spend Controls](/v2/docs/spend-controls-guide) and [Fees and Rewards](/v2/docs/fees-and-rewards).
### Step 3 — Create the Account
Create the checking account from the template, with the customer as its holder. See [Create Accounts](/v2/docs/create-accounts-guide) for the full request and for account relationships.
We refer to the resulting account's UUID as `{ACCOUNT_ID}`.
### Step 4 — Find Your Card Product
List your card products and pick the debit product you intend to issue against. You need one product per form — a virtual product and a physical product.
```shell Shell theme={"system"}
curl -X GET "$baseurl/v2/cards/products" \
-H "Authorization: Bearer $apikey"
```
Check that `active` is `true`, and note the `id` of each. We refer to them as `{VIRTUAL_CARD_PRODUCT_ID}` and `{PHYSICAL_CARD_PRODUCT_ID}`. See [Card Products](/v2/docs/card-products) for what each field on the product controls.
### Step 5 — Issue a Virtual Card
Issue the virtual card as the last step of onboarding, so the customer can spend immediately.
```shell Shell theme={"system"}
curl -X POST "$baseurl/v2/cards" \
-H "Authorization: Bearer $apikey" \
-H 'Content-Type: application/json' \
--data-binary '{
"type": "DEBIT",
"card_details": {
"form": "VIRTUAL",
"account_id": "{ACCOUNT_ID}",
"customer_id": "{CUSTOMER_ID}",
"card_product_id": "{VIRTUAL_CARD_PRODUCT_ID}"
}
}'
```
Virtual cards activate automatically — the card comes back `ACTIVE`, with no activation step.
Show the card details to the customer with the [Reveal Card widget](/v2/docs/card-widgets-reveal), and prompt them to set a PIN with the [Set PIN widget](/v2/docs/card-widgets-set-pin).
Then prompt the customer to add the card to Apple Pay or Google Wallet. See [Digital Wallets and Tokenization](/v2/docs/digital-wallets).
### Step 6 — Issue a Physical Card
```shell Shell theme={"system"}
curl -X POST "$baseurl/v2/cards" \
-H "Authorization: Bearer $apikey" \
-H 'Content-Type: application/json' \
--data-binary '{
"type": "DEBIT",
"card_details": {
"form": "PHYSICAL",
"account_id": "{ACCOUNT_ID}",
"customer_id": "{CUSTOMER_ID}",
"card_product_id": "{PHYSICAL_CARD_PRODUCT_ID}",
"emboss_name": {
"line_1": "Jane Smith"
},
"shipping": {
"method": "LOCAL_MAIL",
"recipient_name": "Jane Smith"
}
}
}'
```
If you omit `emboss_name`, the card is embossed with the customer's first and last name. If you omit `shipping.address`, the card goes to the customer's shipping address on file.
> [!TIP]
>
> For customers who have specified a chosen name, set `emboss_name` explicitly with their chosen and last name rather than relying on the default.
### Step 7 — Track Fulfillment
Subscribe to `CARD.*` webhooks. You receive `CARD.CREATED` on issuance and `CARD.UPDATED` as the card moves through `ORDERED`, `SHIPPED`, and any rejection, which is what you need to keep the customer informed. See the [Webhooks guide](/v2/docs/webhooks-guide).
### Step 8 — Activate the Physical Card
When the card arrives, the customer proves possession.
See [Activate a Card](/v2/docs/issue-a-card#activate-a-card) for the details and trade-offs.
The physical card keeps the PIN the customer already set on the virtual card only if the physical card was issued as a reissuance of the virtual card. Issued independently, as here, it needs its own PIN — prompt for one at activation.
## Running the Program
### Authorization and Declines
Synctera evaluates each funding request against the available balance, account standing, spend controls, address verification, and fraud rules. A decline carries a `data.reason` naming which check failed — `INSUFFICIENT_FUNDS`, `SPEND_CONTROL_VIOLATED`, `ADDRESS_VERIFICATION_FAILED`, and so on.
If you hold state Synctera does not, you can join the authorization flow and return an approve or decline decision per transaction. See [FinTech in the Auth Flow](/v2/docs/card-transactions#fintech-in-the-auth-flow).
### Spend Controls
Spend controls limit how much can be spent, over what window, on which payment types, and at which merchant categories. They attach to the **account**, so if you need per-card limits, give each card its own account under a funding hierarchy. See [Spend Controls](/v2/docs/spend-controls-guide) and [Card-Account Relationship and Funding Hierarchies](/v2/docs/card-accounts-funding).
### Card Lifecycle
The rest of the lifecycle is covered in [Manage a Card](/v2/docs/manage-a-card):
* **Lock and unlock** a card when a customer misplaces it
* **Reissue** on expiration, loss, theft, or damage
* **Terminate** when the customer closes the card
Set up expiration reissuance early. Use [List Cards](/v2/reference/listcards) with the `expires_before` filter to find cards approaching expiry, and reissue them with `EXPIRATION` before the date arrives — the replacement keeps the same PAN and PIN, and inherits the customer's digital wallet tokens, so the customer notices nothing.
### Disputes
Cardholders can dispute any card transaction. Raising a dispute opens a case in the Synctera Console and starts the investigation. See [Card Transaction Disputes](/v2/docs/card-transaction-disputes).
# Prepaid Card
Source: https://docs.synctera.com/v2/docs/build-prepaid-card
A prepaid card is a stored-value card. Funds are loaded onto it in advance and the cardholder can only spend what is loaded — there is no deposit relationship and no credit line behind it.
Prepaid cards reach customers that debit and credit products cannot. They need no credit check and, for some types, no bank account, which makes them the usual instrument for gifting, disbursements, and serving the unbanked and underbanked.
In the Synctera platform a prepaid card is attached to a **prepaid account**. The account is a ledger record rather than a deposit account: the balance is the card. Prepaid cards are restricted from debiting the account directly and are limited to card spend.
Prepaid cards are either **reloadable** or **non-reloadable** - see details below.
## Overview
### Key Concepts
> [accordion] Stored value and the prepaid account
>
> A prepaid card spends from a balance loaded in advance, not from an ongoing deposit relationship. The linked account uses the `PREPAID` account type, and the card uses the `PREPAID` card type — the same card type covers both reloadable and non-reloadable cards.
>
> Because the balance is the product, prepaid accounts restrict which payment rails are available and how funds can arrive. Cardholders are not given the account number, which is what keeps unsupported inbound transfers out.
> [accordion] Account programs
>
> Prepaid accounts carry funding, spend, and rail restrictions that must hold for the life of the account. Those are enforced by an **account program** — a set of characteristics that stay immutable across the account's lifecycle, applied at the account template level.
>
> Synctera sets up the account program and the matching account template during onboarding, based on whether your product is reloadable or non-reloadable. Account programs use spend controls, rail restrictions, and where applicable bank-enforced KYC requirements.
>
> This means almost no setup work on your side: pass the `account_template_id` you were given at onboarding, and every account created from it inherits the right behavior. See [Account Programs](/v2/docs/create-accounts-guide#account-programs).
> [accordion] Funding channels and load limits
>
> Funding is restricted to methods that do not require the cardholder to know an account number — direct deposit, cash and check deposits, internal transfers, and AFT/OCT.
>
> The card networks impose load limits, which differ by type:
>
> | | Reloadable | Non-reloadable |
> | - | - | - |
> | Daily cash | \$5,000 | \$500 |
> | Daily electronic | No restriction | \$500 |
> | Monthly combined | \$150,000 | Not applicable |
>
> For a non-reloadable product, a one-time funding spend control is applied by the account program and cannot be changed at the account level.
### Reloadable and Non-Reloadable
This is the decision that shapes everything else about the program.
| | Reloadable | Non-reloadable |
| - | - | - |
| Loading | Topped up repeatedly for ongoing use | Loaded once, cannot be replenished once spent |
| Best for | The unbanked and underbanked, payroll and EWA, teens and students, gig payouts, corporate and government disbursements | Gifting, privacy, one-off purchases, store credit, refunds, incentives |
| Account type | `PREPAID` | `PREPAID` |
| KYC | Required | Generally not required — some banks may still require it |
| Cardholder name on card | Required | Not required; cards can carry a generic program name |
| Cash and ATM access | Yes | No |
| Inbound AFT | Allowed | Not allowed |
| Tokenization | Supported | Supported with restrictions — one device, no card-on-file, USD only |
| Cashback at point of sale | Allowed | Not allowed |
| Merchant acceptance | Wide, though some high-risk and subscription merchants block prepaid | Narrowest of the card types; many online merchants block anonymous cards that cannot be verified by AVS |
| Dispute rights | Yes, under Regulation E | Limited or none |
> [!NOTE]
>
> A non-reloadable card cannot be converted to a reloadable one. If a customer qualifies for a reloadable product later, issue a new account and a new card.
### How It Differs from a Debit Card
| | Prepaid | Debit |
| - | - | - |
| Funds come from | A balance loaded in advance | The customer's deposit account |
| Underlying account | A prepaid ledger account; the balance is the card | A deposit account the customer holds |
| Funding channels | Restricted to methods not requiring an account number | No restrictions |
| Load limits | Set by the network | None |
| Payment rails | Card spend only; other rails disabled | ACH, wire, P2P, card |
| MCC restrictions | Common, especially for non-reloadable | Rare, use-case dependent |
See [Debit Card](/v2/docs/build-debit-card).
### What Synctera Configures for You
Prepaid programs need more platform-side setup than debit, and almost all of it happens before you write code.
| Object | What it does | Who sets it up |
| - | - | - |
| Account program | Fixes the account type, KYC requirements, payment rails, and spend controls for the life of the account | Synctera, during onboarding |
| Account template | Carries the account program, so accounts created from it inherit its settings | Synctera, during onboarding |
| Spend controls | Enforce the one-time funding restriction on non-reloadable products and any load limits | Synctera, as part of the account program |
| Card product | The BIN, network product type, and card art for your prepaid cards | Synctera, with your sponsor bank and the network |
Prepaid programs must be registered and approved with the card network, and the card art has network-specific requirements. Your Implementation & Onboarding manager handles both.
> [!NOTE]
>
> Prepaid cards require additional configuration for your tenant on Synctera. Work with your Synctera Implementation & Onboarding manager to get set up.
## API Flow
Once your account program and template exist, issuing a prepaid card is a short sequence.
```mermaid mermaid theme={"system"}
%%{init: {"fontFamily": "sans-serif"}}%%
flowchart TB
A["Create the customer"] --> B["Record disclosures"]
B --> C["Verify the customer"]
C --> D["Open the prepaid account
with your account_template_id"]
D --> E["Issue the card"]
E --> F["Load funds"]
```
The `curl` examples assume you have set up `baseurl` and `apikey` environment variables. See [Base URL](/v2/reference/environments) and [Authentication](/v2/reference/authentication).
### Step 1 — Create the Customer
Collect the customer's personal information and create the person. See [Create a Personal Customer](/v2/docs/create-a-personal-customer).
We refer to the resulting UUID as `{CUSTOMER_ID}`.
### Step 2 — Record Disclosures
Record the customer's acknowledgement of each required disclosure, one call per disclosure. See [Record Disclosure Acceptance](/v2/docs/record-disclosure-acceptance).
### Step 3 — Verify the Customer
**Reloadable** products require KYC. The customer must reach a `verification_status` of `ACCEPTED` before the account can be opened. See [KYC/KYB Verification](/v2/docs/kyc-kyb-verification).
**Non-reloadable** products generally do not require KYC, though your sponsor bank may still require document verification. Where KYC is not required, the account program carries the exemption — you do not handle it in your own code.
Where your sponsor bank requires enhanced due diligence, upload it against the customer record. See [Enhanced Due Diligence](/v2/docs/enhanced-due-diligence-guide).
### Step 4 — Open the Prepaid Account
Create the account from the template you were given at onboarding. That template carries the account program, so the account inherits the correct funding limits, rail restrictions, and spend controls.
```shell Shell theme={"system"}
curl -X POST "$baseurl/v2/accounts" \
-H "Authorization: Bearer $apikey" \
-H 'Content-Type: application/json' \
--data-binary '{
"account_type": "PREPAID",
"account_template_id": "{ACCOUNT_TEMPLATE_ID}",
"customer_id": "{CUSTOMER_ID}"
}'
```
Use the reloadable or non-reloadable template as appropriate — they are different templates carrying different programs. See [Create Accounts](/v2/docs/create-accounts-guide).
We refer to the resulting account's UUID as `{ACCOUNT_ID}`.
### Step 5 — Issue the Card
Issue against the prepaid account with `"type": "PREPAID"`. Virtual and physical cards are both supported.
```shell Shell theme={"system"}
curl -X POST "$baseurl/v2/cards" \
-H "Authorization: Bearer $apikey" \
-H 'Content-Type: application/json' \
--data-binary '{
"type": "PREPAID",
"card_details": {
"form": "VIRTUAL",
"account_id": "{ACCOUNT_ID}",
"customer_id": "{CUSTOMER_ID}",
"card_product_id": "{CARD_PRODUCT_ID}"
}
}'
```
For a non-reloadable card where no cardholder name is required, the card carries a generic program name instead. Physical cards require activation; virtual cards do not. See [Issue a Card](/v2/docs/issue-a-card).
### Step 6 — Load Funds
Load the card through one of the permitted funding channels. The common pattern is an internal transfer from a pre-funded account you maintain on the platform. See [Internal Transfers](/v2/docs/internal-transfer-guide).
For a non-reloadable product, the account program's spend control permits a single funding transaction. Further load attempts are declined.
### Step 7 — Ship in Bulk, If Applicable
Gift and incentive programs frequently ship cards in bulk to a business for on-site distribution. Cards can be issued against a business without naming a cardholder, then assigned to individuals later with [Update Card](/v2/reference/updatecard).
See [Bulk Card Orders](/v2/docs/bulk-card-orders).
## Running the Program
### Spend and Restrictions
Prepaid accounts allow card spend and disable the other payment rails. MCC restrictions are common — particularly on non-reloadable products, where high-risk categories and merchants that place large authorization holds, such as travel, lodging, and fuel, are often blocked.
See [Spend Controls](/v2/docs/spend-controls-guide).
### Tokenization
Both types can be added to a digital wallet, but non-reloadable cards carry network restrictions: one device, no card-on-file, and USD transactions only. Tokenization requires an email address and phone number for the cardholder.
See [Digital Wallets and Tokenization](/v2/docs/digital-wallets).
### Fees
Fees are more common on prepaid than on debit — activation, monthly maintenance, reload, ATM, inactivity, and FX. Configure them as rules bundled into a fee product linked to the account template. See [Fees and Rewards](/v2/docs/fees-and-rewards).
### Statements
Sending prepaid cardholders monthly statements is not a requirement. It is, however, a requirement to make accessible the card's full online transaction history.
See [Statements](/v2/docs/statements-guide).
### Disputes
Reloadable cards carry Regulation E dispute rights. Non-reloadable cards have limited or no protection, and what applies may depend on merchant policy. See [Card Transaction Disputes](/v2/docs/card-transaction-disputes).
# Revolving Credit Card
Source: https://docs.synctera.com/v2/docs/build-revolving-credit-card
A credit line where cardholders can carry a balance from one billing cycle to the next, paying interest on the unpaid amount. Revenue comes from interest and fees rather than interchange alone.
A revolving credit card gives the cardholder a credit line they can draw on, repay, and draw on again. Unlike a charge card, the balance does not have to be cleared each cycle — whatever is carried forward accrues interest. That difference is what makes the product a lending business rather than a payments one.
## Overview
### Key Concepts
Three mechanisms define how a revolving credit program behaves. Everything else follows from how you configure them.
> [accordion] Underwriting and the credit limit
>
> Before a card is issued, someone decides whether to extend credit and how much. The outcome is a **credit limit** — the maximum balance the cardholder may carry — which is set on the account and governs how much spending power the card has.
>
> Available credit is the limit minus the current balance, so it falls as the cardholder spends and recovers as they repay.
>
> Underwriting can run on Synctera or on your own platform. See [Who Decides What](#who-decides-what).
> [accordion] Billing and interest accrual
>
> The account is billed on a **cycle**, usually monthly. At the end of each cycle Synctera closes the period and produces a statement showing the transactions, the statement balance, the minimum payment due, and the due date.
>
> Interest accrues on balances carried past the due date, at the APR configured for the account. Because interest is calculated from balances the platform holds, **Synctera is the source of truth for interest and fee calculations**.
> [accordion] Payments and the grace period
>
> The cardholder chooses how much to pay: the full statement balance, the minimum due, or something in between. What they choose determines what interest they pay.
>
> A **grace period** is an interval after the statement date during which paying in full avoids interest on purchases. Paying less than the full balance typically forfeits it for that cycle.
### How It Differs from a Charge Card
Synctera supports both. The distinction matters because it changes the account type, the disclosures, and the economics.
| | Revolving credit card | Charge card |
| - | - | - |
| Carrying a balance | Allowed across cycles | Must be paid in full each cycle |
| Interest | Accrues on carried balances | None, since nothing is carried |
| Payment options | Full, minimum, or partial | Full balance only |
| Primary revenue | Interest and fees, plus interchange | Interchange and fees |
| Account type | `CREDIT_CARD` | `CHARGE_SECURED`, `CHARGE_UNSECURED` |
See [Secured Smart Card](/v2/docs/build-smart-card) and [Unsecured Charge Card](/v2/docs/build-charge-card) for the charge products.
### Who Decides What
A revolving program has more moving parts than a debit program, and they are not all on the same side.
| Responsibility | Options |
| - | - |
| **Underwriting** | Synctera's decisioning workflow, or your own engine. With your own, you decide off-platform and report the outcome back. |
| **Capital** | Whoever funds the receivable — you, a debt provider, or your sponsor bank. |
| **Authorization decisions** | Synctera checks account standing, spend controls, AVS, and fraud. If you hold state Synctera does not — an external credit line, for instance — you can join the authorization flow and approve or decline each transaction yourself. |
| **Interest and fee calculation** | Synctera, always. |
| **Collections** | Typically you, or a servicer you appoint. |
## API Flow
> [!NOTE]
>
> Revolving credit cards require additional configurations for your tenant on Synctera. Please work with your Synctera Implementation & Onboarding manager to get set up.
The rest of this guide walks the sequence from a new customer to a live card.
```mermaid mermaid theme={"system"}
%%{init: {"fontFamily": "sans-serif"}}%%
flowchart TB
A["Create and verify the customer"] --> B["Record disclosures"]
B --> C["Create the application"]
C --> D{"Decision"}
D -->|Approved| E["Create the account
with credit_limit"]
D -->|Declined| F["Record an adverse action"]
E --> G["Issue the card"]
G --> H["Add authorized users"]
```
### Step 1 — Create and Verify the Customer
For a consumer program, create the person and run KYC. For a business program, create the business, run KYB, and create each beneficial owner as a person in their own right.
* [Create a Personal Customer](/v2/docs/create-a-personal-customer)
* [Create a Business](/v2/docs/create-a-business)
* [KYC/KYB Verification](/v2/docs/kyc-kyb-verification)
If you run identity verification with your own vendor, report the results to Synctera rather than having Synctera re-run them. See [External Vendor KYC/KYB Verification](/v2/docs/external-vendor-kyc-kyb-verification).
Where the sponsor bank requires it, upload enhanced due diligence against the person or business record. See [Enhanced Due Diligence](/v2/docs/enhanced-due-diligence-guide).
For a business program, link each beneficial owner to the business with [Create Relationship](/v2/reference/createrelationship). A person is a beneficial owner if they hold 25 percent or more of the equity interest; people with significant management responsibility need a relationship too.
### Step 2 — Record Disclosures
Record the customer's acknowledgement of each required disclosure.
See [Record Disclosure Acceptance](/v2/docs/record-disclosure-acceptance).
### Step 3 — Create the Application
A revolving credit account cannot be created without an application. Even when you have already approved the customer on your own platform, this call is what starts the issuing process on Synctera.
```shell Shell theme={"system"}
curl -X POST "$baseurl/v2/applications" \
-H "Authorization: Bearer $apikey" \
-H 'Content-Type: application/json' \
--data-binary '{
"type": "CREDIT_CARD",
"account_template_id": "{ACCOUNT_TEMPLATE_ID}",
"provider": "loanpro",
"applicant": {
"type": "personal",
"personal": {
"person_id": "{PERSON_ID}"
}
}
}'
```
`type`, `account_template_id`, `provider`, and `applicant` are required. `requested_credit_limit` is optional, in cents.
See [Credit Applications](/v2/docs/credit-applications-guide) and [Create Application](/v2/reference/createapplication).
### Step 4 — Record the Credit Decision
**If Synctera runs underwriting**, the decisioning workflow returns the outcome and updates the application.
**If you run your own underwriting**, patch the application with the result:
```shell Shell theme={"system"}
curl -X PATCH "$baseurl/v2/applications/{APPLICATION_ID}" \
-H "Authorization: Bearer $apikey" \
-H 'Content-Type: application/json' \
--data-binary '{
"applicant": {
"type": "personal",
"personal": {
"person_id": "{PERSON_ID}"
}
},
"status": "completed",
"decision": "approved",
"credit_limit": 500000,
"interest_rate": 1250
}'
```
`credit_limit` is in cents and `interest_rate` is in basis points, so the values above are a \$5,000 limit at 12.50% APR. Both may be omitted.
An approved application comes back with a status of `CREDIT_APPROVED`. Once an account is created from it, the status becomes `CREDIT_ACCEPTED_BY_CUSTOMER`.
See [Update Application](/v2/reference/patchapplication).
### Step 5 — Handle a Declined Application
If the application is declined, the applicant must receive an adverse action notice. Under Regulation B and the FCRA this has to reach them within 30 days of the decision and must state the specific reasons for denial, along with the required ECOA and enforcement agency language.
Create the record with [Create Adverse Action](/v2/reference/createadverseaction), then mark the application `CREDIT_DENIED` with the adverse action ID attached. This is required for personal customers and optional for business customers.
See [Adverse Actions](/v2/docs/adverse-actions-guide).
### Step 6 — Create the Account
Create the account from the template configured for your revolving product, referencing the approved application.
```shell Shell theme={"system"}
curl -X POST "$baseurl/v2/accounts" \
-H "Authorization: Bearer $apikey" \
-H 'Content-Type: application/json' \
--data-binary '{
"account_type": "CREDIT_CARD",
"account_template_id": "{ACCOUNT_TEMPLATE_ID}",
"application_id": "{APPLICATION_ID}",
"customer_id": "{CUSTOMER_ID}"
}'
```
> [!NOTE]
>
> **The credit limit is not set here.** It comes from the approved application — the `credit_limit` recorded in [Step 4](#step-4--record-the-credit-decision) — and the account inherits it through `application_id`. There is no `credit_limit` field on a `CREDIT_CARD` account.
You can attach `fee_product_ids`, `reward_product_ids`, and `spend_control_ids` here, or inherit them from the template. See [Create Accounts](/v2/docs/create-accounts-guide), [Fees and Rewards](/v2/docs/fees-and-rewards), and [Spend Controls](/v2/docs/spend-controls-guide).
### Step 7 — Issue the Card
Issue against the revolving account with `"type": "CREDIT"`, using a card product on a BIN with unsecured credit enabled.
```shell Shell theme={"system"}
curl -X POST "$baseurl/v2/cards" \
-H "Authorization: Bearer $apikey" \
-H 'Content-Type: application/json' \
--data-binary '{
"type": "CREDIT",
"card_details": {
"form": "VIRTUAL",
"account_id": "{ACCOUNT_ID}",
"customer_id": "{CUSTOMER_ID}",
"card_product_id": "{CARD_PRODUCT_ID}"
}
}'
```
Issue the virtual card first so the customer can spend immediately, then the physical card if your program offers one. Physical cards require activation; virtual cards do not. See [Issue a Card](/v2/docs/issue-a-card).
Both forms can be added to Apple Pay and Google Wallet. See [Digital Wallets and Tokenization](/v2/docs/digital-wallets).
### Step 8 — Add Authorized Users
Business programs often issue additional cards to employees. Each authorized user's card is issued against the same revolving account, so all spend draws on one credit line.
**1. Create the person**
Create the authorized user as a person and verify them. See [Create a Personal Customer](/v2/docs/create-a-personal-customer).
**2. Link them to the account**
Give them a relationship to the revolving account with [Create Account Relationship](/v2/reference/createaccountrelationship).
**3. Issue their card**
Issue against the same `account_id`, with the authorized user as `customer_id`.
To control spend per authorized user rather than across the whole account, see the funding hierarchy options in [Card-Account Relationship and Funding Hierarchies](/v2/docs/card-accounts-funding).
## Running the Program
### Authorization
Synctera evaluates each authorization against account standing, spend controls, address verification, and fraud rules. A transaction that would take the balance past the credit limit is declined.
If you hold state that Synctera does not — an external credit line, your own exposure rules — you can join the authorization flow and return an approve or decline decision per transaction. The network imposes a hard response deadline, and a late response means the transaction is declined automatically.
See [FinTech in the Auth Flow](/v2/docs/card-transactions#fintech-in-the-auth-flow).
### Statements
At the end of each billing cycle Synctera closes the period and generates a statement, including a PDF. Subscribe to the statement webhook to know when one is ready, then retrieve it with [List Statements](/v2/reference/liststatements) and [Get Statement PDF](/v2/reference/getstatementpdf).
Regulation requires that statements be available to the customer in your application and as a downloadable PDF, and that customers can request paper statements.
See [Statements](/v2/docs/statements-guide).
### Payments
Record payments against the account with [Make Payment](/v2/reference/makepayment). Synctera applies the payment and recalculates the balance, the available credit, and any interest.
Where you own the repayment experience and collect funds outside Synctera, you still report the portion allocated to card spend so the platform's balances stay correct.
### Interest and Fees
Synctera calculates and posts interest and fees to the account. Common triggers:
* No payment by the due date — a late fee may be assessed and interest accrues on the full statement balance
* A payment below the minimum due — a late fee may be assessed and interest accrues on the unpaid balance
* A payment above the minimum but below the statement balance — interest accrues on the unpaid portion
Cross-border and FX fees are separate from credit fees and are triggered by where the card is used. They are configured on the card product and in your fee rules. See [Fees and Rewards](/v2/docs/fees-and-rewards).
The complete set of rules and fees for your program is defined in the card agreement.
### Rewards
Rewards are applied automatically when their conditions are met — a cleared transaction, for example — and posted to the account as a statement credit. See [Fees and Rewards](/v2/docs/fees-and-rewards).
### Disputes
Cardholders can dispute any card transaction. Raising a dispute opens a case in the Synctera Console and starts the investigation. See [Card Transaction Disputes](/v2/docs/card-transaction-disputes).
### Delinquency and Collections
Your program configuration sets how long past the due date a card is suspended, when the customer is reported delinquent, and when the balance is charged off. Collections are typically your responsibility or a servicer's.
### Credit Bureau Reporting
Because balances and payment history live on the account, a revolving program can furnish to the credit bureaus. Furnishing requires bureau credentialing for your program, arranged with your Synctera representative.
# Secured Smart Card
Source: https://docs.synctera.com/v2/docs/build-smart-card
A charge card secured by funds the cardholder already holds. It runs on credit rails without underwriting, and the security stays accessible — unlike a traditional secured card, the deposit is not locked away.
A Secured Smart Card gives a customer a charge card backed by their own money. What makes it different from a traditional secured card is that the security is **dynamic**: spending power tracks the available balance of a linked deposit account rather than a fixed deposit locked up front. The cardholder keeps access to their funds, and the card's spending power adjusts as they spend, repay, and move money.
That combination — credit rails, no underwriting, funds that stay accessible — is why it works as a credit-building product for customers who could not qualify for an unsecured card.
**Why FinTechs offer it**
* Runs on credit rails, which generally earn higher interchange than debit
* No underwriting or credit check is required
* Payment history can be furnished to the bureaus, so it builds credit
* Credit risk is mitigated by the security the customer already holds
> [!NOTE]
>
> Credit products require specific privileges on your organization. Work with your Synctera Implementation & Onboarding manager before planning one.
## Overview
### Key Concepts
> [accordion] Dynamic security
>
> The product is two accounts: a deposit account holding the customer's money, and a `CHARGE_SECURED` account the card spends against. The charge account's available credit mirrors the **available balance** of the deposit account.
>
> The security must be a `CHECKING` or `SAVING` account, named by `security.linked_account_id` on the charge account.
>
> Because the link is to available balance rather than a locked deposit, the customer can still move their money. Move funds out and spending power falls to match; deposit more and it rises.
> [accordion] Charge, not revolving
>
> The balance must be paid in full each billing cycle. Nothing carries over, so no interest accrues.
>
> Two settings govern the cycle. `billing_period` sets the frequency and the day the cycle anchors to. `grace_period` sets how many days past the end of the cycle the customer has before payment is due.
>
> A card that lets balances carry is a different product — see [Revolving Credit Card](/v2/docs/build-revolving-credit-card).
> [accordion] Credit building
>
> Because the account has a balance and a payment history, it can be furnished to the credit bureaus in a way a debit card cannot. This is usually the reason a customer chooses the product.
>
> Furnishing requires bureau credentialing for your program, arranged with your Synctera representative.
### How Balances Work
This is the part worth understanding before you build, because the two accounts move together and a charge account's balance reads the opposite way to a deposit account's.
```mermaid mermaid theme={"system"}
%%{init: {"fontFamily": "sans-serif"}}%%
flowchart LR
D["Deposit account
(security)"] -->|"available balance sets
available credit"| C["CHARGE_SECURED
account"]
C --> K["Credit card"]
```
Starting from a security account funded with $100, the charge account shows $100 of available credit. A \$20 card purchase then does two things at once:
| | Available | Balance |
| - | - | - |
| **Security** | \$80 | \$100 |
| **Secured charge** | \$80 | \$20 |
The purchase reduces available credit on the charge account **and** places a hold on the security for the same amount. The security still holds $100, but only $80 of it is available. That hold stays until the charge balance is repaid.
> [!NOTE]
>
> A secured charge account is a **credit** account, so its balance expresses what has been **spent**, not what is held. This is the opposite of a `CHECKING` or `SAVING` account. Keep the distinction in mind when you display balances to customers.
If the customer then moves money out of the security, available credit falls to match — the security's available balance is always what governs. A transfer that would take available balance below the outstanding hold fails with a balance violation.
For the full worked sequence, including repayment, see [Balance management](/v2/docs/secured-sc-accounts-guide#balance-management).
### How It Differs from Other Cards
| | Secured Smart Card | Unsecured Charge Card | Revolving Credit Card | Debit |
| - | - | - | - | - |
| Backed by | The customer's own deposits | A credit line | A credit line | The deposit account itself |
| Underwriting | None | Required | Required | None |
| Carrying a balance | Not allowed | Not allowed | Allowed | Not applicable |
| Interest | None | None | On carried balances | None |
| Builds credit | Yes | Yes | Yes | No |
| Account type | `CHARGE_SECURED` | `CHARGE_UNSECURED` | `CREDIT_CARD` | `CHECKING` |
### Who Decides What
| Responsibility | Who |
| - | - |
| **Credit limit** | Effectively the customer, through what they hold in the security account. No credit decision is made. |
| **Authorization** | Synctera, against available credit, account standing, spend controls, and fraud rules. |
| **Repayment** | The customer, in full each cycle — or Synctera, if autopay is enabled. |
| **Statements** | Synctera generates a combined statement covering both accounts. |
| **Bureau furnishing** | Synctera, once credentialing is in place. |
## API Flow
```mermaid mermaid theme={"system"}
%%{init: {"fontFamily": "sans-serif"}}%%
flowchart TB
A["Create and verify the customer"] --> B["Record disclosures"]
B --> C["Create the deposit account
(the security)"]
C --> D["Create the CHARGE_SECURED account
linked to the security"]
D --> E["Issue the card"]
E --> F["Enable autopay, if offered"]
```
### Step 1 — Create and Verify the Customer
Create the person and complete KYC. See [Create a Personal Customer](/v2/docs/create-a-personal-customer) and [KYC/KYB Verification](/v2/docs/kyc-kyb-verification).
### Step 2 — Record Disclosures
Record the customer's acknowledgement of each required disclosure. Three are specific to this product:
| Disclosure type | Covers |
| - | - |
| `SC_ACCOUNT_AGREEMENT` | The Smart Card account agreement |
| `SC_SECURITY_AGREEMENT` | The security agreement over the linked deposit account |
| `SC_AUTO_PAYMENT` | The customer's opt-in to automatic payments, if you offer them |
Your onboarding disclosures apply as well. See [Record Disclosure Acceptance](/v2/docs/record-disclosure-acceptance).
### Step 3 — Create the Application
A charge secured account can optionally include an application, created through the Application API. See [Credit Applications](/v2/docs/credit-applications-guide).
If an application is denied — whether for KYC failure or another reason — adverse action reasons must be sent to personal customers, and the adverse action ID included when the application is marked `CREDIT_DENIED`. This is optional for business customers. See [Adverse Actions](/v2/docs/adverse-actions-guide).
### Step 4 — Create the Security Account
Create the `CHECKING` or `SAVING` account that will back the card. A customer's existing DDA can serve as the security, which is what lets them keep using those funds.
See [Using a customer DDA as a linked security account](/v2/docs/secured-sc-accounts-guide#using-a-customer-dda-as-a-linked-security-account).
We refer to the resulting account's UUID as `{SECURITY_ACCOUNT_ID}`.
### Step 5 — Create the Secured Charge Account
Create the `CHARGE_SECURED` account, pointing its `security.linked_account_id` at the deposit account from the previous step.
```shell Shell theme={"system"}
curl -X POST "$baseurl/v2/accounts" \
-H "Authorization: Bearer $apikey" \
-H 'Content-Type: application/json' \
--data-binary '{
"account_type": "CHARGE_SECURED",
"account_template_id": "{ACCOUNT_TEMPLATE_ID}",
"customer_id": "{CUSTOMER_ID}",
"security": {
"linked_account_id": "{SECURITY_ACCOUNT_ID}"
}
}'
```
The template carries the billing period and grace period for the product. See [Creating a `CHARGE_SECURED` account](/v2/docs/secured-sc-accounts-guide#creating-a-chargesecured-account).
We refer to the resulting account's UUID as `{ACCOUNT_ID}`.
### Step 6 — Issue the Card
Issue against the charge account with `"type": "CREDIT"`, using a card product on a BIN that supports credit. Physical and virtual cards are both supported.
```shell Shell theme={"system"}
curl -X POST "$baseurl/v2/cards" \
-H "Authorization: Bearer $apikey" \
-H 'Content-Type: application/json' \
--data-binary '{
"type": "CREDIT",
"card_details": {
"form": "VIRTUAL",
"account_id": "{ACCOUNT_ID}",
"customer_id": "{CUSTOMER_ID}",
"card_product_id": "{CARD_PRODUCT_ID}"
}
}'
```
See [Issue a Card](/v2/docs/issue-a-card).
### Step 7 — Enable Autopay, If Offered
Autopay pays the balance from the security account so a customer who forgets does not fall delinquent. It runs only when a regular payment has **not** been received in time.
Two settings control it:
| Field | Meaning |
| - | - |
| `is_system_auto_pay_enabled` | Whether autopay runs. Defaults to `false`. |
| `auto_payment_period` | Days past the end of the billing period before autopay fires. `0` means the statement date. Maximum 28, and must not exceed `grace_period`. |
Synctera validates that `is_system_auto_pay_enabled` cannot be set to `true` unless that customer has acknowledged the `SC_AUTO_PAYMENT` disclosure. So there are two orderings:
* **Opt in during onboarding.** Record the disclosure, then create the account with `is_system_auto_pay_enabled` set to `true`.
* **Opt in later.** Create the account with the default `false`. When the customer opts in, record the disclosure, then patch the flag to `true`.
## Running the Program
### Repayment
The balance is due in full each cycle, by the date the `grace_period` sets. Payments reduce the charge account balance and release the corresponding hold on the security, restoring spending power.
### Statements
At the end of each billing cycle Synctera generates a combined statement covering both the security and the secured charge account. See [Secured Charge Statements](/v2/docs/charge-secured-statements-guide).
### Spend Controls
Spend controls apply to the charge account and limit spend by amount, window, payment type, and merchant category. See [Spend Controls](/v2/docs/spend-controls-guide).
### Disputes
Cardholders can dispute any card transaction. See [Card Transaction Disputes](/v2/docs/card-transaction-disputes).
# Bulk Card Orders
Source: https://docs.synctera.com/v2/docs/bulk-card-orders
The Synctera platform supports the issuance of cards in bulk and can be configured for automatic daily fulfillment or fulfillment at your request.
> [!WARNING]
>
> ### In order to create bulk orders your card product needs to be configured for bulk issuance.
## Bulk Order Creation Steps
### 1. Create a Bulk Order Configuration
A bulk order configuration provides the shipping instructions for individual bulk orders. Once a bulk order configuration has been set up in the Synctera system, cards can be issued in bulk and will be shipped to the destination specified in the configuration. Fulfillment of the bulk order configuration is based on the bulk issuance policy specified in the configuration.
#### Bulk Issuance Policy
| Bulk Issuance Policy | Description |
| - | - |
| AUTO | Bulk orders configured with an AUTO fulfillment policy will be fulfilled nightly at 9:30pm PST (UTC -8:00). All cards that have been issued with the corresponding bulk order config id prior to the cut-off time will be included in the daily bulk order. |
| MANUAL | Bulk orders configured with a MANUAL fulfillment policy will be fulfilled at the request of the integrator. All cards that have been issued with the corresponding bulk order config id prior to the requested fulfillment will be included in the bulk order. |
Call [POST /v1/cards/bulk\_issuance](/v2/reference/createbulkorderconfig) to create a bulk order config.
```sh Shell theme={"system"}
-X POST \
$baseurl/v1/cards/bulk_issuance \
-H "Authorization: Bearer $apikey" \
-H 'Content-Type: application/json' \
--data-binary '
{
"name": "Sample Bulk Order Config",
"card_product_id": {CARD_PRODUCT_ID},
"bulk_issuance_policy": "AUTO",
"shipping": {
"recipient_name": {
"first_name": "Jane",
"last_name": "Smith"
},
"address": {
"address_line_1": "123 Main St",
"city": "Seattle",
"state": "WA",
"postal_code": "98109",
"country_code": "US"
},
"method": "INTERNATIONAL"
}
}'
```
This will return a response with the created bulk order configuration:
```json JSON theme={"system"}
{
"id": "7d943c51-e4ff-4e57-9558-08cab6b963c7",
"creation_time": "2010-05-06T12:23:34.321Z",
"name": "Sample Bulk Order Config",
"card_product_id": "7d943c51-e4ff-4e57-9558-08cab6b963c7",
"shipping": {
"recipient_name": {
"first_name": "Jane",
"last_name": "Smith"
},
"address": {
"address_line_1": "123 Main St",
"city": "Seattle",
"state": "WA",
"postal_code": "98109",
"country_code": "US"
},
"is_expedited_fulfillment": false,
"method": "INTERNATIONAL",
},
"bulk_issuance_policy": "AUTO",
"tenant": "abcdef_ghijkl"
}
```
Note the returned `id` attribute. This is used in future card issuance requests in order to include the card as part of a bulk shipment and in order to fulfill bulk orders configured for `MANUAL` fulfillment.
### 2. Issue Cards
Cards are dynamically added to a bulk order by providing the bulk order configuration `id` in the card issuance request.
Call [POST /v1/cards](/v2/reference/issuecard) to issue a card.
### 3. Fulfill Bulk Order
> [!NOTE]
>
> ### bulk order configurations with an auto policy are automatically fulfilled nightly at 9:30pm PST (UTC -8:00)
#### Manual Order Fulfillment
Call [POST /v1/cards/bulk\_issuance](/v2/reference/fulfillbulkorder) to fulfill the bulk order.
```sh Shell theme={"system"}
-X POST \
$baseurl/v1/cards/bulk_issuance/{$bulk_order_config_id}/fulfill \
-H "Authorization: Bearer $apikey"
```
This will return a `202 Accepted` response. All cards issued with the corresponding bulk order config id since the last fulfillment request will be included in the bulk order.
#### Card Fulfillment
Once a card has been shipped a webhook will be triggered with the updated shipping details. Including a tracking number if available.
To subscribe to the `CARD.UPDATED` webhook refer to the [Webhooks Guide](/v2/docs/webhooks-guide).
# Business Expense Cards
Source: https://docs.synctera.com/v2/docs/business-card
This guide will show how to set up business expense cards in Synctera's platform.
In this guide we will create a business expense account which will fund card purchases made by the business's employees, subject to spending controls. The purpose of this guide is to give an overview of how the various entities in Synctera's platform work together to be able to handle this type of use case.
## Prerequisites
Before continuing in this guide you will also need a card product set up using a commercial BIN. We will refer to its UUID as `{{card_product_id}}`.
Please also have a business created and fully verified such that is has a `verification_status` of `"ACCEPTED"`. We will refer to the UUID of this business as `{{business_id}}`.
You will also need one or more persons in the system that have been verified and passed KYC. This means they must have a `kyc_status` of `"ACCEPTED"`. We will refer to their UUIDs as `{{employee1_id}}`, `{{employee2_id}}`, etc. Refer to the [KYC Verification API Overview](/v2/reference/verify) for the process to get your customers verified.
## Business expense account
Create an account template by performing a [POST /v0/accounts/templates](/v2/reference/createaccounttemplate) with the following request body.
```json JSON theme={"system"}
{
"name": "business expense accounts",
"is_enabled": true,
"template": {
"account_type": "CHECKING",
"bank_country": "US",
"currency": "USD",
"is_ach_enabled": false,
"is_card_enabled": false,
"is_p2p_enabled": true
}
}
```
Note that cards are not enabled for accounts created using this template but the accounts can be funded via P2P transactions (money movement within Synctera's platform).
The request should return a new account template. We will refer to this template's UUID as `{{business_account_template_id}}`.
Using this new template, create a new account by performing a [POST /v0/accounts](/v2/reference/createaccount) with the following request body.
```json JSON theme={"system"}
{
"account_template_id": "{{business_account_template_id}}",
"relationships": [
{
"relationship_type": "ACCOUNT_HOLDER",
"business_id": "{{business_id}}"
}
]
}
```
We will refer to this new account's UUID as `{{business_account_id}}`. Because we disabled cards in the account template, we can not issue cards for this account directly. The cards will be issued against the employee expense accounts which will in turn be connected to this account.
## Spend control
Create a spend control rule by performing a [POST /v0/spend\_controls](/v2/reference/createspendcontrol) with the following request body. For more details, see the [spend controls guide](/v2/docs/spend-controls-guide).
```json JSON theme={"system"}
{
"name": "Employee monthly limit",
"amount_limit": 100000,
"time_range": {
"time_range_type": "ROLLING_WINDOW_DAYS",
"days": 30
},
"action_decline": true,
"action_case": false,
"is_active": true
}
```
The request should return a new spend control rule. We will refer to this rule's UUID as `{{spend_control_id}}`.
## Employee expense accounts
Create another account template by performing a [POST /v0/accounts/templates](/v2/reference/createaccounttemplate) with the following request body.
```json JSON theme={"system"}
{
"is_enabled": true,
"name": "employee spending accounts",
"template": {
"account_type": "CHECKING",
"bank_country": "US",
"currency": "USD",
"balance_floor": {
"balance": 0,
"linked_account_id": "{{business_account_id}}"
},
"balance_ceiling": {
"balance": 0,
"linked_account_id": "{{business_account_id}}"
},
"is_ach_enabled": false,
"is_card_enabled": true,
"is_p2p_enabled": false,
"spend_control_ids": [
"{{spend_control_id}}"
]
}
}
```
This request references the spend control.
This request also includes balance floor and balance ceiling objects. The balance floor is zero and the `overdraft_account_id` refers to the business account we created earlier. This means that for any account created using this template, the business account will provide real-time funding in order to keep the account's balance at or above zero. Similarly, the balance ceiling is also zero and the `overflow_account_id` also refers to the business account we created earlier. This means that for any account using this template, the business account will receive funds flowing in to the account in order to keep the account's balance at or below zero. In other words, accounts created using this template never hold a balance and card transactions on these accounts effectively move money to and from the business account. The accounts are still limited by their individual spending limits of \$1000 per month. For more information, see the guide [Balance Floor and Ceiling and Linked Accounts](/v2/docs/balance-floor-ceiling).
Note that the only payment rail enabled for this account template is cards.
The request should return a new account template. We will refer to this template's UUID as `{{employee_account_template_id}}`.
With this template we can now create accounts for all the business's employees by performing a [POST /v0/accounts](/v2/reference/createaccount) with the following request body.
```json JSON theme={"system"}
{
"account_template_id": "{{employee_account_template_id}}",
"relationships": [
{
"relationship_type": "ACCOUNT_HOLDER",
"customer_id": "{{employee1_id}}"
}
]
}
```
This will create a new account. We will refer to the new account's ID as `{{employee1_account_id}}`. Repeat this request using `{{employee2_id}}` to create `{{employee2_account_id}}`, then using `{{employee3_id}}` to create `{{employee3_account_id}}`, etc.
## Employee cards
Create a card for each employee by performing a [POST /v0/cards](/v2/reference/issuecard) with the following request body. This assumes your card product is for physical cards. For virtual cards replace `"PHYSICAL"` with `"VIRTUAL"`.
```json JSON theme={"system"}
{
"form": "PHYSICAL",
"account_id": "{{employee1_account_id}}",
"card_product_id": "{{card_product_id}}",
"customer_id": "{{employee1_id}}",
"type": "DEBIT"
}
```
Then repeat this request to create cards for the other employees and their accounts.
## Transactions
Experiment with the employee cards by doing some simulated card transactions. Card transaction authorizations will automatically create "JIT funding" transactions between the business account and the respective employee accounts. For example, a $10 authorization for employee 1's card will decrease the balance of the business account by $10 and increase the ledger balance of employee 1's account by $10. This $10 will be placed on hold so the available balance of employee 1's account remains zero. If this authorization is reversed the \$10 automatically moves back into the business account. Card transactions will appear in the employee account transaction histories. There will be corresponding "JIT funding" transactions that appear in the employee accounts and the business accounts.
The monthly limit applies to each employee independently. Any attempt to authorize a transaction over the limit will be declined.
# Card Issuer 3DS
Source: https://docs.synctera.com/v2/docs/card-3ds
"Three Domain Secure" (3DS) is a protocol designed to be an additional security layer for credit and debit card transactions when there is no physical card present, such as in online purchases.
## Overview
When a merchant initiates the 3DS process the Synctera platform responds according to your configuration. You may specify the desired 3DS behaviour at the card product level or on a per-request basis.
### Card Product
Each product can be configured with a `three_ds_policy`. This field has two possible values: `SMS_OTP` and `EXEMPT`. If no value is specified, the default is `SMS_OTP`.
If you choose `SMS_OTP` then for each 3DS process involving the card product the cardholder will receive an SMS message with a one-time code which they must then supply to the merchant to verify their identity. The SMS will be sent to the customer's phone number that is stored in the platform.
If you choose `EXEMPT` then each 3DS process involving the card product will succeed with no further steps.
You may override the card product's 3DS policy by implementing a decision gateway.
### Decision Gateway
3DS decision gateways allow you to make real-time decision about each 3DS request. 3DS gateways are independent entities in the Synctera platform which can be associated with any number of card products. These associations are defined by the `three_ds_decision_gateways` endpoints, not the card product endpoints.
#### Creation
Create a 3DS decision gateway by calling `POST /v1/cards/three_ds_decision_gateways` with a body like this:
```json JSON theme={"system"}
{
"is_active": true,
"decision_url": "https://your.server/3ds_decision",
"card_products": [
"2957a146-ce3b-4d04-8328-ab3ea6e76cac"
],
"fallback_decision": "EXEMPT",
"custom_headers": {
"X-Custom-Data": "arbitrary value"
}
}
```
Every time the Synctera platform makes a 3DS decision for a card from the card products you specify, it will now attempt to send a `POST` request to your `decision_url`. The request will include all the `custom_headers` key-value pairs you specify as HTTP headers in the request.
Custom headers are optional to use as you see fit. For the purpose of authenticating requests, rather than using custom headers, you can [create a signature secret for request validation](/v2/docs/webhooks-guide#integration-steps) and then check the `Synctera-Signature` HTTP header of each request to your gateway.
The `fallback_decision` will be used if something goes wrong and the Synctera platform can't get a response from your decision endpoint or the request times out. The values for `fallback_decision` are the same as the `three_ds_policy` options for a card product (`SMS_OTP` and `EXEMPT`) and have the same meaning.
If an active decision gateway is configured for a card product, then the API responses for that card product will indicate that the `three_ds_policy` is `DECISION_GATEWAY`. This means that the decision gateway overrides the `three_ds_policy` of the card product and if the Synctera platform can't get a response from the decision gateway it will use the gateway's `fallback_decision` rather than the card product's `three_ds_policy`.
#### 3DS Decision Request
The body of the request to your 3DS decision server will look like this:
```json JSON theme={"system"}
{
"card_id": "f8c84f73-91a5-4dfe-9c12-a35bfa1df716",
"card_product_id": "2957a146-ce3b-4d04-8328-ab3ea6e76cac",
"acs_transaction_id": "a0c165f9-23ae-408c-b8c3-a7c486750b1e",
"authentication_request_type": "PAYMENT",
"client_ip_address": "10.1.2.3",
"device_channel": "BROWSER",
"transaction_amount": 6187,
"currency_code": "USD",
"transaction_type": "PAYMENT",
"transaction_sub_type": "PURCHASE",
"merchant": {
"name": "Best Buy",
"country_code": "840",
"id": "345954985882",
"category_code": "5732"
}
}
```
The `transaction_amount` is in minor units of the currency (in this case, cents). The currency is specified in the `currency_code` field as a 3 character alphabetical code.
`authentication_request_type` is one of `PAYMENT`, `RECURRING`, `INSTALLMENT`, `ADD_CARD`, `MAINTAIN_CARD` or `EMV_CARDHOLDER_VERIFICATION`.
`device_channel` is one of `BROWSER`, `APP_BASED` or `THREEDS_REQUESTER_INITIATED`.
`transaction_type` is either `PAYMENT` or `NON_PAYMENT`.
`transaction_sub_type` is one of `PURCHASE`, `ACCOUNT_VERIFICATION`, `ACCOUNT_FUNDING`, `QUASI_CASH` or `PREPAID_ACTIVATION_AND_LOAD`.
The `merchant.country_code` is specified as the ISO 3166-1 three-digit numeric country code.
#### 3DS Decision Response
To indicate your 3DS decision, your 3DS decision server responds with HTTP status OK (200) and writes a single field the response body. For example:
```json JSON theme={"system"}
{
"decision": "EXEMPT"
}
```
The allowed values for your `decision` are `SMS_OTP` and `EXEMPT`. These values have the same meaning as described above for the `three_ds_policy` of a card product.
If the Synctera platform sees a response status code other than 200 or can't decode the response body then it will use the gateway's `fallback_decision`.
# Card-Account Relationship and Funding Hierarchies
Source: https://docs.synctera.com/v2/docs/card-accounts-funding
Every card is linked to an account, and that account is what the card spends against. The account type you choose follows from the card type, and the funding structure follows from your use case.
This guide covers three decisions that shape how money reaches your cards: which account type backs each card type, whether cards draw on their funding account directly or through a hierarchy, and how many cards an account can hold.
## Account types
Synctera uses different account types for different card types. In practice you build a separate [account template](/v2/docs/create-accounts-guide) for each card type you offer, and create accounts from that template.
| Card product | Account type | Account guide |
| - | - | - |
| Debit card | `CHECKING` | [Checking and Savings Accounts](/v2/docs/checking-savings-accounts-guide) |
| Reloadable prepaid card | `PREPAID` | [Create Accounts](/v2/docs/create-accounts-guide) |
| Non-reloadable prepaid card | `PREPAID` | [Create Accounts](/v2/docs/create-accounts-guide) |
| Secured Smart Card (charge card) | `CHARGE_SECURED` + a deposit account as security | [Secured Charge Accounts](/v2/docs/secured-sc-accounts-guide) |
| Unsecured Charge Card | `CHARGE_UNSECURED` | [Unsecured Charge Accounts](/v2/docs/unsecured-charge-accounts-guide) |
| Revolving credit card | `CREDIT_CARD` | [Line of Credit Accounts](/v2/docs/line-of-credit-accounts-guide) |
> [!NOTE]
>
> A card account must have cards enabled. Set `is_card_enabled` to `true` on the account template, or on the account itself. Accounts that only fund other accounts — pool accounts and funding parents — normally have cards disabled and P2P enabled instead.
## Funding relationships
How a card is funded depends on whether it spends directly from the account that holds the money, or from an account that is topped up from elsewhere.
### Direct funding
The card is linked directly to the funding account. The balance the cardholder can spend is the balance on that account.
```mermaid mermaid theme={"system"}
%%{init: {"fontFamily": "sans-serif"}}%%
flowchart LR
A["Account
(CHECKING)"] --> C["Card"]
```
Common use cases:
* Consumer debit programs
* Consumer prepaid programs
* Consumer credit programs — these technically fall under direct funding, although the available balance or credit is backed by a linked deposit account or line of credit
### Just-in-time funding
The card is linked to an account that is itself funded by another account, either in real time or through just-in-time (JIT) funding. There can be multiple levels of funding accounts above the card's account.
```mermaid mermaid theme={"system"}
%%{init: {"fontFamily": "sans-serif"}}%%
flowchart LR
A["Funding account
(pool)"] --> B["Card account"] --> C["Card"]
```
Common use cases:
* Commercial and small business debit and prepaid programs
* Commercial credit programs
JIT funding is built with balance floors and ceilings on the card's account, which trigger a transfer from the parent account when the balance falls below the floor. See [Balance Floor and Ceiling and Linked Accounts](/v2/docs/balance-floor-ceiling) for the mechanics, and [Business Expense Cards](/v2/docs/business-card) for a worked example that combines a pool account, per-employee accounts, and spend controls.
## Number of cards per account
The maximum number of cards a person can hold on a card product is configured on the card product itself, through `card_limit`. This limit is not applied to business cards.
* **Consumer programs** are limited to one active (non-terminated) physical card and a small number of active virtual cards per account. The exact virtual card limit is set on your card product — check `card_limit` on the product via [List Card Products](/v2/reference/listcardproducts).
* **Commercial and business programs** have no limit on the number of active physical and virtual cards per active account.
> [!NOTE]
>
> Terminated cards do not count toward the limit. If a customer has reached their limit, terminate an unused card before issuing a new one, or reissue the existing card rather than issuing an additional one.
## Assigning a card to a customer later
A card can be issued against a business without naming a cardholder. Pass `business_id` without `customer_id` at issuance, and the card is created but cannot be activated or used for spend until a person is assigned to it with [Update Card](/v2/reference/updatecard).
This is how bulk programs work: cards are manufactured and shipped to the business in bulk, then assigned to individual employees on site. See [Bulk Card Orders](/v2/docs/bulk-card-orders).
# Card Activation Widget (Deprecated)
Source: https://docs.synctera.com/v2/docs/card-activation-widget-legacy
Using this widget you can add card activation to your website. It requires a Synctera widget vault token to initialize it with. The user will have 5 minutes to complete the activation submission.
> [!WARNING]
>
> This widget is deprecated. For new integrations, use the [Activate Card Widget](/v2/docs/card-widgets-activate).
The Card Activation Widget injects a configurable set of iframes into your app, allowing your user to securely enter a PAN & CVV in a PCI compliant manner. This helps remove some (but not all) of the PCI compliance requirements you would otherwise need to handle.
The iframes injected by Synctera allow you complete control over the styling over the widget using only CSS.
## Quick start
1. Add `` to your page.
2. Embed the Card Activation widgets when and as needed (both the card-pan and card-cvv widgets are needed):
```html HTML theme={"system"}