> ## Documentation Index
> Fetch the complete documentation index at: https://docs.synctera.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Autopay

> 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.
</Warning>

## 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. |

<Info>
  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.
</Info>

## Prerequisites

Before you create an autopay configuration, make sure the following are in place.

<Steps>
  <Step title="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`.
  </Step>

  <Step title="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.
  </Step>

  <Step title="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).
  </Step>

  <Step title="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).
  </Step>

  <Step title="API credentials">
    A valid API key for the Sandbox or Production environment. See [Dev Setup](/v2/docs/dev-setup).
  </Step>
</Steps>

## 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) |

<Info>
  `FIXED_AMOUNT` never overpays. Synctera pays the lesser of the fixed amount and the current balance.
</Info>

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.
</Warning>

### 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.
</Warning>

### 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.

<Info>
  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."
</Info>

### 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

<Steps>
  <Step title="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.

    <CodeGroup>
      ```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}}"
          }
        }'
      ```
    </CodeGroup>

    A `201` response returns the configuration with its `id` and a `status` of `ACTIVE`:

    <CodeGroup>
      ```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"
      }
      ```
    </CodeGroup>

    To pay the minimum due from an external bank account instead, swap the payment method and give ACH enough lead time:

    <CodeGroup>
      ```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"
        }
      }
      ```
    </CodeGroup>
  </Step>

  <Step title="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`.
  </Step>

  <Step title="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).

    <CodeGroup>
      ```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"
      ```
    </CodeGroup>

    <CodeGroup>
      ```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"
          }
        ]
      }
      ```
    </CodeGroup>

    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`.
  </Step>

  <Step title="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.
  </Step>

  <Step title="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.

    <CodeGroup>
      ```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" }'
      ```
    </CodeGroup>

    <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.
    </Warning>
  </Step>

  <Step title="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.

    <CodeGroup>
      ```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" }'
      ```
    </CodeGroup>

    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.
  </Step>

  <Step title="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.

    <Info>
      An account relationship cannot be deleted while an active autopay configuration depends on it. Delete or repoint the autopay configuration first.
    </Info>
  </Step>
</Steps>

## 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)                       |
