> For the complete documentation index, see [llms.txt](https://docs.tradevest.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.tradevest.ai/release-notes/archive/v.2.5.0.md).

# v.2.5.0

**2026-06-09 - Live**

**2026-05-28 - Test Environment**

***

**Added**

**Savings Plans: Lifecycle Webhook**

Partners now receive an asynchronous webhook whenever the state of a savings plan changes, removing the need to poll `GET /savings-plans/{savingPlanId}` for status transitions or validation outcomes.

* **Documentation Location:** API REFERENCE → [Webhooks](/api-reference/webhooks.md)
* **New Endpoint:** `POST /savings-plans-notification` - webhook delivered to the partner's registered endpoint when a savings plan is created, activated, deactivated, deleted, or rejected as invalid
* **New event type:** `SAVINGS_PLANS_NOTIFICATION` on `EventTypeEnum`
* **Payload (`SavingsPlansNotification`) includes:** `savingsPlanId`, `customerId`, `externalId` (optional, partner-supplied at creation), `modifiedOn`, `status` (`ACTIVE` / `INACTIVE` / `DELETED` / `INVALID`), `notificationType`, `validationError` (only present when `status=INVALID`)
* **Validation errors emitted on `INVALID`:** `ALREADY_EXISTS_ERROR`, `DATA_NOT_FOUND_ERROR`, `SAVINGS_PLAN_INVALID_DATA_ERROR`, `UNKNOWN_ERROR` - each delivered with a human-readable `description`
* **Note:** The same `description` text is also surfaced on the `message` field of the `GET /savings-plans/{savingPlanId}` response so partners may choose either delivery channel.

***

**Customer Documents: W-8BEN and W-8IMY Tax Form Support**

Two additional US tax forms are now accepted on document upload and document-type webhooks, expanding the set of tax-documentation use cases partners may submit for natural-person and legal-entity customers.

* **Documentation Location:** API REFERENCE → Documents / API REFERENCE → [Webhooks](/api-reference/webhooks.md)
* **Affected Schemas:** `DocumentTypeEnum`, `DocumentUploadTypeEnum`
* **New enum values:** `W_8BEN`, `W_8IMY` - alongside the existing `W_8BEN_E`
* **Note:** Partners using strict enum validation on document webhooks should add `W_8BEN` and `W_8IMY` to their accepted set before deployment.

***

**Customer Documents: Required Document Missing Validation Error**

A new validation error type is reported when a customer attempts an action (e.g. trading onboarding for a legal entity) without uploading a regulatorily required document.

* **Documentation Location:** API REFERENCE → [Webhooks](/api-reference/webhooks.md)
* **Affected Schema:** `DocumentValidationErrorEnum` (on document validation webhooks)
* **New enum value:** `REQUIRED_DOCUMENT_MISSING` - emitted when a mandatory document for the requested operation has not been uploaded
* **Note:** Partners may use this signal to prompt the customer to upload the missing document instead of treating the rejection as a generic failure.

***

**Customer Documents: `DELETED` Status**

Documents may now be moved into a terminal `DELETED` state - for example when a partner or operator removes a previously uploaded document - and the status is surfaced on both API responses and document webhooks.

* **Documentation Location:** API REFERENCE → Documents / API REFERENCE → [Webhooks](/api-reference/webhooks.md)
* **Affected Schema:** `DocumentStatusEnum`
* **New enum value:** `DELETED` - added alongside the existing `RECEIVED`, `APPROVED`, `REJECTED`, `ARCHIVED`
* **Note:** Partners using strict enum validation should add `DELETED` to their accepted set before deployment.

***

**Fee Templates: Savings Plan Execution Trigger**

A new fee-trigger event allows partners to configure fees that are charged when a savings plan execution runs, in addition to the existing per-trade triggers.

* **Documentation Location:** API REFERENCE → [Products](/documentation/products.md)
* **Affected Schema:** `FeeTriggerEventEnum`
* **New enum value:** `SAVING_PLAN_EXECUTION` - fee is triggered when a savings plan executes its scheduled investment

***

**Changed**

**Savings Plans: External ID Support and `savingsPlanId` Field Rename**

Partners may now attach their own internal identifier to a savings plan at creation time and receive it back on retrieval and webhooks. The plan identifier returned from the create endpoint is renamed for consistency with the rest of the Savings Plans API.

* **Documentation Location:** API REFERENCE → Trading → Savings Plans / API REFERENCE → [Webhooks](/api-reference/webhooks.md)
* **Endpoints:** `POST /savings-plans`, `GET /savings-plans/{savingPlanId}`, savings plans webhook
* **Request Changes (`POST /savings-plans`):**
  * **Added:** `externalId` (string, optional, max 100 chars) - partner-supplied identifier stored alongside the plan
* **Response Changes:**
  * `POST /savings-plans` response - field renamed: `uuid` → `savingsPlanId` (still a UUID, same value semantics)
  * `GET /savings-plans/{savingPlanId}` `SavingsPlan` - added `externalId` (string, optional)
  * Savings plans webhook payload - added `externalId` (string, optional)

***

**Savings Plans: Validation Message on `GET`**

The savings plans retrieval endpoint now returns the reason a plan was rejected, so partners can surface the validation failure directly to the customer without correlating against the webhook.

* **Documentation Location:** API REFERENCE → Trading → [Savings Plans](/api-reference/asset-management/savings-plans.md)
* **Endpoint:** `GET /savings-plans/{savingPlanId}`
* **Added field on `SavingsPlan`:** `message` (string, optional) - present only when `status=INVALID`. Matches the `validationError.description` delivered in the corresponding `SAVINGS_PLANS_NOTIFICATION` webhook.

***

**Savings Plans: Status Enum Realigned with Webhook Lifecycle**

The savings plan status values have been realigned to match the lifecycle now delivered on the webhook, replacing the placeholder `PENDING` and `DELETED` values from v.2.4.0 with the production-accurate `RECEIVED` (creation accepted, awaiting validation) and `INVALID` (validation failed).

* **Documentation Location:** API REFERENCE → Trading → Savings Plans
* **Affected Schema:** `SavingsPlanStatusEnum` (returned on `GET /savings-plans/{savingPlanId}` and `GET /savings-plans`)
* **Changed:**
  * **Removed:** `PENDING`, `DELETED`
  * **Added:** `RECEIVED`, `INVALID`
  * **Unchanged:** `ACTIVE`, `INACTIVE`
* **Note:** This refines the original v.2.4.0 contract before any partner has integrated against it on Live. Plan deletions are reported via the dedicated webhook `SavingsPlansNotificationStatusEnum.DELETED` rather than via the GET-endpoint status. Partners that started wiring against the v.2.4.0 Pretest spec must update their accepted status set on the GET endpoint.

***

**Tokenized Assets: Order Status Enum Updated**

The WAWEX (tokenized asset) order status enum is realigned to British spelling and gains a new terminal status that mirrors the Traditional Trading lifecycle for the case where a partially filled order is then canceled for the remaining quantity.

* **Documentation Location:** API REFERENCE → Trading → [<kbd>Tokenized Assets</kbd>](/api-reference/asset-management/wawex-tokenized-assets/tokenized-assets.md)
* **Affected Schema:** `OrderStatus` on `GET /wawex/orders/{orderId}` and related WAWEX order responses
* **Changed:**
  * **Renamed:** `CANCELED` → `CANCELLED` (British spelling, consistent with `FILLED`, `SETTLED` lifecycle naming)
  * **Added:** `PARTIALLY_FILLED_CANCELLED` - order was partially filled, then the remaining open quantity was canceled

***

**Corporate Actions: Tendered Quantity Minimum Validation**

The tender-instruction endpoint now rejects requests with a `tenderedQuantity` of `0`, reflecting the underlying business rule that a tender instruction must cover at least one share.

* **Documentation Location:** API REFERENCE → Trading → [Corporate Actions](/api-reference/asset-management/corporate-actions.md)
* **Endpoint:** Corporate-action tender-option submission (request body `tenderedQuantity` field)
* **Validation change:** `tenderedQuantity` now requires `minimum: 1` (previously only enforced `multipleOf: 1`, so `0` was technically accepted)
* **Required Partner Action:** Confirm that no client-side flows submit a `tenderedQuantity` of `0` (e.g. as part of clearing a previously entered value). Requests with `tenderedQuantity=0` will now be rejected with a `400 Bad Request`.

***

**Corporate Actions: Additional Date and Status Filters on Per-Customer Endpoint**

The per-customer corporate-actions list endpoint gains five new optional query parameters so partners can narrow results without pulling the full list and filtering client-side.

* **Documentation Location:** API REFERENCE → Trading → [Corporate Actions](/api-reference/asset-management/corporate-actions.md)
* **Endpoint:** `GET /corporate-actions/customers/{customerId}`
* **Added query parameters (all optional, `date-time` format unless noted):**
  * `exDate` - return corporate actions with ex-date on or after this date
  * `paymentDate` - return corporate actions with payment date on or after this date
  * `recordDate` - return corporate actions with record date on or after this date
  * `responseDeadline` - return corporate actions with response deadline on or after this date
  * `status` - filter by `CorporateActionStatusEnum` value
* **Note:** Parameters can be combined freely; omitting a parameter applies no constraint on that field. The platform-wide list endpoint `GET /corporate-actions/` already exposes the same filters - this change brings the per-customer variant to parity.

***

**Tokenized Assets: `PARTIALLY_FILLED_EXPIRED` Order Status**

The WAWEX (tokenized asset) order status enum gains a new terminal status for the case where a partially filled order then expires before the remaining quantity could be filled. This completes the pair started by `PARTIALLY_FILLED_CANCELLED` (introduced earlier in this release).

* **Documentation Location:** API REFERENCE → Trading → [Tokenized Assets](/api-reference/asset-management/wawex-tokenized-assets/tokenized-assets.md)
* **Affected Schema:** `OrderStatus` on `GET /wawex/orders/{orderId}` and related WAWEX order responses
* **Added:** `PARTIALLY_FILLED_EXPIRED` - order was partially filled, then the remaining open quantity expired without further executions
* **Note:** Partners using strict enum validation on WAWEX order responses must add `PARTIALLY_FILLED_EXPIRED` to their accepted set alongside `PARTIALLY_FILLED_CANCELLED`.

***

**Savings Plans: Additional Filters and Pagination on List Endpoint**

The savings-plans list endpoint gains an `externalId` filter and explicit pagination parameters, so partners can locate a plan by their own identifier and page through large result sets without scanning the whole list.

* **Documentation Location:** API REFERENCE → Trading → [Savings Plans](/api-reference/asset-management/savings-plans.md)
* **Endpoint:** `GET /customers/{customerId}/savings-plans`
* **Added query parameters (all optional):**
  * `externalId` (string) - filter by the external identifier set by the partner on `POST /savings-plans`
  * `limit` (integer, default `20`, minimum `1`) - maximum number of results to return per page
  * `cursor` (string) - pagination cursor returned from a previous response
* **Note:** The existing filters (`status`, `instrumentType`, `instrumentIdentifier`, `liquidityCustomerProductId`, `savingsCustomerProductId`) remain unchanged and can be combined with the new parameters.

***

**Traditional Trading: Sort Orders by Execution Amount**

The traditional-assets orders list endpoint gains a `sortDirection` parameter so partners can retrieve orders sorted ascending or descending by execution amount.

* **Documentation Location:** API REFERENCE → Trading → [Traditional Assets](/api-reference/asset-management/trading.md)
* **Endpoint:** `GET /traditional/orders`
* **Added query parameter:** `sortDirection` - accepts the new `SortDirectionEnum` values `ASC` or `DESC`. Sort key is execution amount.
* **New schema:** `SortDirectionEnum` (`ASC` | `DESC`) - added to `openapi/tvda-api/models/` for reuse by future sortable endpoints.
* **Note:** Omitting `sortDirection` preserves the previous unsorted (or insertion-order) behavior, so existing integrations are unaffected.

***

**Deprecated**

**Entities: `riskLevel` Field on Customers**

The `riskLevel` field on the natural-person, legal-entity, and joint-account entity responses is marked deprecated and will be removed in a future major release. The field's value is no longer maintained by the platform.

* **Documentation Location:** API REFERENCE → [Entities](/api-reference/entities.md)
* **Endpoints:** `GET /natural-persons/{naturalPersonId}`, `GET /legal-entities/{legalEntityId}`, `GET /joint-accounts/{jointAccountId}` (and list / webhook variants)
* **Deprecated:** `riskLevel` field on the `NaturalPerson`, `LegalEntity`, and `JointPerson` schemas
* **Replacement:** None - risk-level information is no longer exposed on the partner API
* **Note:** The field is still present in responses for backwards compatibility but its value should not be relied upon. Partners using it for any business logic should remove the dependency before the next major release.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.tradevest.ai/release-notes/archive/v.2.5.0.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
