> This is Payabli documentation. For a complete page index, fetch https://docs.payabli.com/llms.txt — append .md to any page URL for lightweight markdown. For section-level indexes, query parameters, and other AI-optimized access methods, see https://docs.payabli.com/ai-agents.md

# Changelog

This is the changelog for the Payabli Rust SDK. It includes updates, bug fixes, and new features.

## October 27, 2026

## v2.0.21

This release includes breaking changes. It corrects the organization details types to match the API, renames the ticket amount fields on paypoint credentials and the request type for `query.list_organizations`, and adds an organizations client for the intelligent boarding API (beta). See [October 20, 2026](/changelog/api-changelog/2026/10/20) and [October 22, 2026](/changelog/api-changelog/2026/10/22) and [October 27, 2026](/changelog/api-changelog/2026/10/27) for more information.

### Basic organization details return a response envelope

`organization.get_basic_organization` and `organization.get_basic_organization_by_id` now return `Result<GetBasicOrganizationResponse, ApiError>` instead of `Result<OrganizationQueryRecord, ApiError>`. The organization details are in `response_data`, alongside `is_success` and `response_text`.

```rust
// Before
let org: OrganizationQueryRecord = client.organization.get_basic_organization("my-org", None).await?;

// After
let basic: GetBasicOrganizationResponse = client.organization.get_basic_organization("my-org", None).await?;
let org: Option<OrganizationQueryRecord> = basic.response_data;
```

### Organization details types match the API

`OrganizationQueryRecord` changes these field types:

* `billing_info` is now `Option<InstrumentResponse>` instead of `Option<Instrument>`. `InstrumentResponse` has `ach_account`, `ach_routing`, `billing_address`, `billing_city`, `billing_country`, `billing_state`, and `billing_zip` (`Option<String>`).
* `contacts` is now `Option<Vec<ContactsResponse>>` instead of `Option<ContactsField>`. `ContactsResponse` has `contact_name`, `contact_email`, `contact_title`, and `contact_phone`.
* `org_logo` is now `Option<String>`, the logo's URL, instead of `Option<FileContent>`.

It also adds `org_favicon` (`Option<String>`), the URL of the organization's favicon. The field names are unchanged, but their JSON names now match the PascalCase names the API returns, such as `OrgId` and `BillingInfo`.

### Ticket amount fields renamed

`PayabliCredentialsPascal` renames `max_ticket` to `maxticket` and `min_ticket` to `minticket`.

```rust
// Before
let credentials = PayabliCredentialsPascal {
    max_ticket: Some(MaxTicket(1000.0)),
    min_ticket: Some(MinTicket(1.0)),
    ..Default::default()
};

// After
let credentials = PayabliCredentialsPascal {
    maxticket: Some(MaxTicket(1000.0)),
    minticket: Some(MinTicket(1.0)),
    ..Default::default()
};
```

### `ListOrganizationsQueryRequest` renamed

The request type for `query.list_organizations` is now `QueryListOrganizationsQueryRequest`, because the new organizations client has its own list request. The fields are unchanged.

```rust
// Before
let orgs = client.query.list_organizations(123, &ListOrganizationsQueryRequest::default(), None).await?;

// After
let orgs = client.query.list_organizations(123, &QueryListOrganizationsQueryRequest::default(), None).await?;
```

### Organizations client (beta)

`ApiClient` adds `organizations`, with `list_organizations`, `create_organization`, `get_organization`, and `update_organization`. `list_organizations` takes `&OrganizationsListOrganizationsQueryRequest`, and `create_organization` takes `&CreateOrganizationOrganizationsRequest`, which holds one of `CreateOrganizationWithInlineBusiness`, `CreateOrganizationWithBusinessReference`, or `CreateOrganizationAllFields`. The methods return envelope types, such as `PaypointDetailEnvelope`. These endpoints only accept OAuth. See [OAuth authentication](/developers/oauth-authentication).

```rust
let detail: PaypointDetailEnvelope = client.organizations.get_organization("org-reference", None).await?;
```

### Other changes

* `MethodsListOut` adds `rtp` and `wire` (`Option<bool>`).
* `PaypointSummaryResponse` adds `external_id` (`Option<String>`).

## October 19, 2026

## v2.0.20

This release includes breaking changes. It adds clients for the intelligent boarding API (beta) and marks the legacy boarding methods as deprecated. See [October 19, 2026](/changelog/api-changelog/2026/10/19) for more information.

### Intelligent boarding clients (beta)

`ApiClient` adds the `businesses`, `people`, `paypoints`, `payment_methods`, `boarding_templates`, and `applications` clients. Their methods return envelope types, such as `BusinessDetailEnvelope`.

These endpoints only accept OAuth. Set your OAuth `client_id` and `client_secret` in `ClientConfig`. See [OAuth authentication](/developers/oauth-authentication) and [Manage API credentials](/guides/platform-developer-api-credentials-manage).

```rust
let config = ClientConfig {
    client_id: Some("CLIENT_ID".to_string()),
    client_secret: Some("CLIENT_SECRET".to_string()),
    ..Default::default()
};
let client = ApiClient::new(config).expect("Failed to build client");
let business = client.businesses.get_business("BUSINESS_REFERENCE", None).await?;
```

### Legacy boarding methods are deprecated

Legacy boarding will be sunset in Q2 2027. Every method on `boarding` and `templates` now has a deprecation warning in its documentation. `export.export_applications` was already deprecated. The methods don't have the `#[deprecated]` attribute, so the compiler doesn't warn you.

### Renamed request types

Three request types were renamed so they don't collide with the new clients' types. Their fields haven't changed.

| Method                       | Before                         | After                                  |
| ---------------------------- | ------------------------------ | -------------------------------------- |
| `boarding.list_applications` | `ListApplicationsQueryRequest` | `BoardingListApplicationsQueryRequest` |
| `templates.list_templates`   | `ListTemplatesQueryRequest`    | `TemplatesListTemplatesQueryRequest`   |
| `query.list_paypoints`       | `ListPaypointsQueryRequest`    | `QueryListPaypointsQueryRequest`       |

### `ApiError::UnprocessableEntityError` has new fields

The new applications endpoints return a different error body for HTTP `422`. `ApiError::UnprocessableEntityError` now has `message`, `field`, and `validation_error` instead of `message`, `is_success`, `response_code`, `response_text`, and `response_data`. Code that matches on the old fields no longer compiles.

```rust
// After
if let Err(ApiError::UnprocessableEntityError { message, field, validation_error }) = &result {
    // ...
}
```

### Case management bank account services use new types

`BankAccountServices::money_in` is now `Option<Vec<CaseManagementMoneyInService>>`, and `money_out` is now `Option<Vec<CaseManagementMoneyOutService>>`. The new enumerations have the same variants as `MoneyInService` and `MoneyOutService`.

```rust
// Before
money_in: Some(vec![MoneyInService::Ach]),

// After
money_in: Some(vec![CaseManagementMoneyInService::Ach]),
```

### New `pagination` module

The new `pagination` types module has the same name as the `pagination` module that the crate root already re-exports, so imports that start with `payabli_api::pagination::`, such as `use payabli_api::pagination::AsyncPaginator;`, no longer compile. Import `AsyncPaginator`, `SyncPaginator`, and `PaginationResult` from the crate root or from `payabli_api::core::pagination` instead. The new `Pagination` type is available from the crate root and the prelude.

## v2.0.19

This release adds methods to get the next check number and cancel ghost cards, a check number on reissued payouts, invoice data on subscription updates, a 1099 flag on vendors, every payout that paid a bill, and card-present device details. See [October 19, 2026](/changelog/api-changelog/2026/10/19) for more information.

### New methods

* `money_out.get_next_check_number(paypoint_id: i64, account_id: &str, options)` returns `Result<NextCheckNumberResponse, ApiError>`. `NextCheckNumberResponse::check_number` is a `String`.
* `ghost_card.delete_ghost_card(card_token: &str, options)` returns `Result<DeleteGhostCardResponse, ApiError>`. Its `response_data` has `delete_type` and `card_token` (`Option<String>`).

```rust
let next: NextCheckNumberResponse = client.money_out.get_next_check_number(285, "ACCOUNT_ID", None).await?;
let deleted: DeleteGhostCardResponse = client.ghost_card.delete_ghost_card("CARD_TOKEN", None).await?;
```

### Request changes

* `ReissueOutRequest` adds `check_number` (`Option<VendorCheckNumber>`).
* `RequestUpdateSchedule`, the request for `subscription.update_subscription`, adds `invoice_data` (`Option<BillData>`).
* `VendorData` adds `issue_1099` (`Option<bool>`).

### Vendor 1099 flag

`VendorQueryRecord`, `VendorDataResponse`, `TransferOutDetailVendor`, and `PayoutSubscriptionVendor` add the required field `issue_1099` (`Issue1099`, a tuple struct that wraps a `bool`). `AssociatedVendor`, `VCardGetResponseAssociatedVendor`, `VendorOutData`, and `GetMethodResponseResponseDataVendorsItem` add `issue_1099` (`Option<Issue1099>`).

### Payouts that paid a bill

`BillResponseData` and `BillQueryRecord2` add `transactions` (`Option<Vec<BillTransactionReference>>`). Each `BillTransactionReference` has `id_out` (`i64`) and `payment_id` (`Option<String>`).

### Card-present device details

* `TransactionQueryRecords` and `TransactionQueryRecordsCustomer` add `device_entry_mode` (`Option<DeviceEntryMode>`), `emv_auth_data` (`Option<EmvAuthData>`, with `request_emv_data` and `response_emv_data`), and `device_data` (`Option<QueryDeviceData>`).
* `DeviceQueryRecord` adds the required field `operational_status` (`DeviceQueryRecordOperationalStatus`, with the variants `Online`, `Busy`, and `Offline`), plus `app_version` and `os_version` (`Option<String>`).

Builders for `VendorQueryRecord`, `VendorDataResponse`, `TransferOutDetailVendor`, `PayoutSubscriptionVendor`, and `DeviceQueryRecord` fail with `BuildError` when a new required field is missing. Struct literals of the changed types must set the new fields.

## October 14, 2026

## v2.0.18

This release includes breaking changes. The get payout subscription response now uses its own camelCase types, which fixes vendor fields that came back empty. See [October 14, 2026](/changelog/api-changelog/2026/10/14) for more information.

### New types in the get payout subscription response

`PayoutSubscriptionQueryRecord` now uses new types for its vendor, bills, and payment data:

| Field          | Before                        | After                                   |
| -------------- | ----------------------------- | --------------------------------------- |
| `vendor`       | `Option<VendorQueryRecord>`   | `Option<PayoutSubscriptionVendor>`      |
| `bill_data`    | `Option<Vec<BillPayOutData>>` | `Option<Vec<PayoutSubscriptionBill>>`   |
| `payment_data` | `Option<QueryPaymentData>`    | `Option<PayoutSubscriptionPaymentData>` |

`PayoutSubscriptionPaymentData::payment_details` is an `Option<PayoutSubscriptionPaymentDetails>`. Update any code that names the old types:

```rust
// Before
let vendor: Option<VendorQueryRecord> = record.vendor;

// After
let vendor: Option<PayoutSubscriptionVendor> = record.vendor;
```

### New payment data type in list payout subscriptions

`PayoutSubscriptionQueryRecordPascal::payment_data` is now an `Option<PayoutSubscriptionPaymentDataPascal>` instead of an `Option<QueryPaymentData>`.

### New fields on payout subscriptions

`PayoutSubscriptionQueryRecord` and `PayoutSubscriptionQueryRecordPascal` add `same_day_ach`, `do_not_create_bills`, `allow_duplicated_bills`, `auto_convert_same_day_ach` (`Option<bool>`), and `subscription_type` (`Option<String>`). The payment data types add `wallet_type` and `payor_signature`, and `PayoutSubscriptionPaymentDetails` adds the payout details fields, such as `order_id`.

### Vendor record changes

`VendorQueryRecord::stored_methods` is now an `Option<Vec<VendorStoredMethod>>`. `VendorStoredMethod` adds `is_default` and nests the existing stored-method fields under `vendor_response_stored_method_fields`, so their access path changes:

```rust
// Before
let masked_account = &method.masked_account;

// After
let masked_account = &method.vendor_response_stored_method_fields.masked_account;
```

`VendorQueryRecord` adds `vendor_portal` (`Option<VendorPortalAccess>`), and `BillingDataResponse` adds `country` (`Option<String>`).

## October 5, 2026

## v2.0.17

This release includes breaking changes. The notification log and stored payment method types now match what the API returns, and OCR results have new amount fields. See [September 22, 2026](/changelog/api-changelog/2026/9/22), [September 29, 2026](/changelog/api-changelog/2026/9/29), [October 1, 2026](/changelog/api-changelog/2026/10/1), [October 2, 2026](/changelog/api-changelog/2026/10/2), and [October 5, 2026](/changelog/api-changelog/2026/10/5) for more information.

### Notification log retry methods return new types

`notificationlogs.retry_notification_log` now returns `Result<NotificationRetryResponse, ApiError>` instead of `Result<NotificationLogDetail, ApiError>`. `NotificationRetryResponse` has a single `message` field. `notificationlogs.bulk_retry_notification_logs` now returns `Result<String, ApiError>` instead of `Result<(), ApiError>`.

```rust
// Before
let log: NotificationLogDetail = client.notificationlogs.retry_notification_log("UUID", None).await?;

// After
let retry: NotificationRetryResponse = client.notificationlogs.retry_notification_log("UUID", None).await?;
let message: String = retry.message;
let bulk: String = client
    .notificationlogs
    .bulk_retry_notification_logs(&BulkRetryRequest(vec!["UUID".to_string()]), None)
    .await?;
```

### Notification log fields moved to a base type

The shared notification log fields now live in the new `NotificationLogBase` type, flattened into `NotificationLog` and `NotificationLogDetail` as `notification_log_base_fields`. On `NotificationLog`, these fields were top-level. On `NotificationLogDetail`, they were in `notification_log_fields: NotificationLog`.

```rust
// Before
let id = &log.id;
let id = &detail.notification_log_fields.id;

// After
let id = &log.notification_log_base_fields.id;
let id = &detail.notification_log_base_fields.id;
```

* `response_status` is now `String` instead of `Option<String>`. It holds a status message such as `OK`. The HTTP status code is in the new `response_status_code` (`i64`).
* `NotificationLogBase` adds the required fields `organization_name`, `paypoint_name`, `request_id`, and `response_status_code`.
* `NotificationLog` adds the required fields `notification_type`, `organization_logo`, `organization_fav_icon`, and `paypoint_logo`.
* On `NotificationLogDetail`, `response_content` is now `String` instead of `Option<String>`.

Builders for these types fail with `BuildError` when a new required field is missing.

### Customer fields on stored payment methods

`GetMethodResponseResponseDataCustomersItem` no longer has `payor_data_request_fields: PayorDataRequest`. Its fields are now top-level and match the customer record. `first_name` and `last_name` are now `firstname` and `lastname`.

```rust
// Before
let first = &customer.payor_data_request_fields.first_name;

// After
let first = &customer.firstname;
```

#### Moved, removed, and added fields

Moved from `payor_data_request_fields` to the top level: `company`, `customer_id`, `customer_number`, `identifier_fields`, `shipping_address_1` (now `Option<Shippingaddressadditional>`), `shipping_city`, `shipping_country`, `shipping_state`, and `shipping_zip`.

Removed: `additional_data`, `billing_address_1`, `billing_address_2`, `billing_city`, `billing_country`, `billing_email`, `billing_phone`, `billing_state`, `billing_zip`, and `shipping_address_2`.

Added: `additional_fields`, `address`, `address_1`, `city`, `country`, `customer_events`, `customer_portal`, `email`, `phone`, `shipping_address`, `state`, and `zip`.

### New response fields

* `AddMethodResponse` adds `page_identifier`, and `AddMethodResponseResponseData` adds `auth_code`, `avs_response_text`, `cvv_response_text`, and `vendor_id`.
* `GetMethodResponseResponseData` adds `wallet_type`.
* `OcrResultData` adds `total_amount` and `discount` (`Option<f64>`).

## September 18, 2026

## v2.0.16

Regenerated the Rust SDK to incorporate latest API documentation improvements. See [September 18, 2026](/changelog/api-changelog/2026/9/18) for more information.

## September 16, 2026

## v2.0.15

Regenerated the Rust SDK to incorporate latest API documentation improvements. See [September 16, 2026](/changelog/api-changelog/2026/9/16) for more information.

## September 10, 2026

## v2.0.14

Regenerated the Rust SDK to incorporate latest API documentation improvements. See [September 10, 2026](/changelog/api-changelog/2026/9/10) for more information.

## September 9, 2026

## v2.0.13

Regenerated the Rust SDK to incorporate latest API documentation improvements. See [September 8, 2026](/changelog/api-changelog/2026/9/8) for more information.

## August 28, 2026

## v2.0.12

### New `business_summary` field on `PaypointData`

`PaypointData` now includes `business_summary`, a business description from boarding. See [August 28, 2026](/changelog/api-changelog/2026/8/28) for more information.

## August 17, 2026

## v2.0.10

### Refund methods now take an optional request body

`MoneyIn::refundv_2` and `MoneyIn::refundv_2_amount` now take `Option<&RefundV2Request>` instead of `&RefundV2Request`. Wrap existing request bodies in `Some(...)`:

```rust
// Before
client
    .money_in
    .refundv_2(
        &trans_id,
        &RefundV2Request { amount: Some(60.0), ..Default::default() },
        None,
    )
    .await?;

// After
client
    .money_in
    .refundv_2(
        &trans_id,
        Some(&RefundV2Request { amount: Some(60.0), ..Default::default() }),
        None,
    )
    .await?;
```

You can also pass `None` for a standard refund with no request body:

```rust
client.money_in.refundv_2(&trans_id, None, None).await?;
```

## July 28, 2026

## v2.0.9

Regenerated the Rust SDK to incorporate latest API documentation improvements. See [July 28, 2026](/changelog/api-changelog/2026/7/28) for more information.

## July 27, 2026

## v2.0.8

Added OAuth2 client-credentials support. Set `client_id`/`client_secret` on `ClientConfig` instead of `api_key` and the SDK handles the token exchange and refresh automatically:

```rust
let config = ClientConfig {
    client_id: Some(CLIENT_ID.to_string()),
    client_secret: Some(CLIENT_SECRET.to_string()),
    base_url: Environment::Sandbox.url().to_string(),
    ..Default::default()
};

let client = ApiClient::new(config).expect("Failed to build client");
```

The existing `api_key` field still works unchanged — no action needed if you're not switching auth methods. See the [Rust SDK guide](/developers/platform-sdk-rust-guide) and [Authentication](/developers/authentication) to compare both methods.

## July 20, 2026

## v2.0.5

Changed the `VendorQueryRecord.additional_data` type from `HashMap<String, HashMap<String, serde_json::Value>>` to `HashMap<String, String>` to match the API.

## June 30, 2026

## v2.0.2

Regenerated the Rust SDK to incorporate latest API documentation improvements. See [June 30, 2026](/changelog/api-changelog/2026/6/30) for more information.

## June 11, 2026

## v2.0.1

Regenerated the Rust SDK to incorporate latest API documentation improvements. See [June 11, 2026](/changelog/api-changelog/2026/6/11) for more information.

## June 8, 2026

## v2.0.0

As part of an ongoing effort to improve the consistency and usability of our SDKs, we've updated the SDK generation process.
This update introduces breaking changes to the SDK.
All breaking changes affect only method signatures and namespacing, not core record types or properties.
SDK initialization, configuration, business logic, and workflows remain unchanged.
For more information on precise method signatures and example usage, please see the [SDK reference on GitHub](https://github.com/payabli/sdk-rust/blob/main/reference.md).

### Request body wrapper types removed

The following types are deleted. Their fields are now on the parent request struct directly.

#### Removed types and their replacements

| Removed type              | Fields now on         | Method                                   |
| ------------------------- | --------------------- | ---------------------------------------- |
| `SubscriptionRequestBody` | `RequestSchedule`     | `subscription.new_subscription`          |
| `AuthorizePayoutBody`     | `RequestOutAuthorize` | `money_out.authorize_out`                |
| `ReissuePayoutBody`       | `ReissueOutRequest`   | `money_out.reissue_out`                  |
| `PaymentPageRequestBody`  | `PayLinkDataInvoice`  | `payment_link.add_pay_link_from_invoice` |

The `money_out.authorize_out` method also gains `allow_duplicated_bills`, `do_not_create_bills`, and `force_vendor_creation` as direct fields on `RequestOutAuthorize`.
The `payout_subscription.create_payout_subscription` method changes its request type from `PayoutSubscriptionRequestBody` to `RequestPayoutSchedule`.

### `PayMethodCredit.method` is now a required typed enum

```rust
// Before
PayMethodCredit { method: "card".to_string(), .. }

// After
PayMethodCredit { method: PayMethodCreditMethod::Card, .. }
```

Affects `MoneyIn::getpaid`, `getpaidv_2`, `authorize`, `authorizev_2`, `Subscription::new_subscription`, and `TokenStorage::add_method`.

### Field type changes

#### Full list

| Field                                           | Old type                             | New type                                 |
| ----------------------------------------------- | ------------------------------------ | ---------------------------------------- |
| `BillItem.item_cost`                            | Required `f64`                       | `Option<f64>` — wrap with `Some(5.0)`    |
| `CustomerData.identifier_fields` inner elements | `Vec<Option<String>>`                | `Vec<String>` — remove `Some()` wrappers |
| `BillOutData.terms`                             | `Terms("NET30".to_string())` newtype | `Terms::Net30` enum variant              |
| `BillOutData.vendor`                            | `VendorData`                         | `BillOutDataVendor`                      |

### Boarding structs changed to tuple newtypes

`ApplicationDataPayInServicesAch` and `ApplicationDataPayInServicesCard` changed from named-field structs to tuple structs. `ApplicationDataPayInContactsItem` and `ApplicationDataPayInOwnershipItem` follow the same pattern.

```rust
// Before
services: ApplicationDataPayInServices {
    ach: ApplicationDataPayInServicesAch {
        ach_setup_fields: AchSetup { ..Default::default() },
        ..Default::default()
    },
    ..Default::default()
}

contacts: Some(vec![ApplicationDataPayInContactsItem {
    contacts_fields: Contacts { contact_name: Some("...".to_string()), ..Default::default() },
    ..Default::default()
}])

// After
services: ApplicationDataPayInServices {
    ach: ApplicationDataPayInServicesAch(AchSetup { ..Default::default() }),
    ..Default::default()
}

contacts: Some(vec![ApplicationDataPayInContactsItem(Contacts {
    contact_name: Some("...".to_string()),
    ..Default::default()
})])
```

## May 20, 2026

## v1.0.18

Fixed an issue where the Rust SDK wasn't properly deserializing the `extra_data` field in certain API response models.

## May 11, 2026

## v1.0.17

Regenerated the Rust SDK to incorporate latest API documentation improvements. See [May 11, 2026](/changelog/api-changelog/2026/5/11) for more information.

## May 8, 2026

## v1.0.15

Fixed a bug that caused the `CustomerSummary` object to be deserialized incorrectly in customer records.
Fixed a bug that caused the `InvoiceData` object to be deserialized incorrectly in transaction records.
Regenerated the Rust SDK to incorporate latest API definition updates.

## April 13, 2026

## v1.0.10

Regenerated the Rust SDK to incorporate latest API documentation improvements. See [April 13, 2026](/changelog/api-changelog/2026/4/13) for more information.

_Showing the 20 most recent of 27 entries. Append `/llms.txt` to the changelog URL for the complete index._