> This page is for Enterprise.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://citi-demo.ferndocs.com/enterprise/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://citi-demo.ferndocs.com/enterprise/_mcp/server.

# Create a Virtual Account

POST https://tts.sandbox.apib2b.citi.com/citiconnect/sb/receivablesservices/v1/virtualaccount/activateorreserve
Content-Type: application/json

This endpoint allows you to create a virtual account with activation and reservation services. The endpoint supports both XML and JSON format. The activation and reservation functionality is identified based on the `action` in the request payload.

Reference: https://citi-demo.ferndocs.com/enterprise/enterprises/api-reference/account-services/virtual-accounts-api/virtual-accounts-single-entity/virtual-account-activate-or-reserve

## Authentication

- `Authorization` header (bearer token, required) — All CitiConnect APIs use the oAuth2 authentication scheme, which requires a bearer token to authenticate your API call. The Token URL includes the version of authentication used by this API. See the Citi Authentication API reference for information on requesting a token.

## Request

### Query parameters

- `client_id` (string, required) — This is your unique identifier shared during your CitiConnect API onboarding. This is the same `client_id` used for OAuth token generation.

### Headers

- `Authorization` (string, required) — The OAuth Token prefixed with "Bearer" and space in between.

### Body (application/json)

This endpoint expects a VirtualAccountRequest.

- `action` (enum, required) — Action is a request type. if you are requesting to activate a virtual account, then provide action values as ``activation``. If requesting to reserve virtual accounts for a previously cited virtual header account then provide action value as ``reservation``.
  - Allowed values: `reservation`, `activation`
- `api_version` (string, required) — Version of the API.
- `branch_code` (string, required) — Citi branch code associated with a given virtual header account.
- `contact_email` (string, required) — Email address as defined on the virtual header account.
- `contact_first_name` (string, required) — First name as defined on the virtual header account.
- `contact_last_name` (string, required) — Last name as defined on the virtual header account.
- `contact_phone` (string, required) — Phone number as defined on the virtual header account.
- `virtual_header_account` (string, required) — Physical account in a VAM structure.
- `accounts` (list of Account, optional) — Mandatory only if value of 'action' parameter is 'activation'.This parameter specifies the list of Virtual Accounts.
- `number_of_accounts_required` (integer, optional) — Mandatory parameter only if the value of 'action' parameter is 'reservation', and specifies the number of virtual accounts requested to be reserved.

## Response

### 202

Accepted

- `message` (string, required) — Detailed response description for given request.
- `request_id` (string, required) — Auto-generated unique identification assigned for the request.
- `status` (string, required) — Status of the request.

## Errors

### 400 Bad Request Error

Bad Request

- `code` (string, optional) — The code which categorize the https error, to compile recognize at application, i.e. CC00003,CC00004,CC00005 etc
- `error_details` (list of ErrorDetail, optional)
- `message` (string, optional) — message for error
- `ref_id` (string, optional) — unique reference ID for a particular request
- `status` (string, optional) — https status code

### 401 Unauthorized Error

Unauthorized

- `code` (string, optional) — The code which categorize the https error, to compile recognize at application, i.e. CC00003,CC00004,CC00005 etc
- `error_details` (list of ErrorDetail, optional)
- `message` (string, optional) — message for error
- `ref_id` (string, optional) — unique reference ID for a particular request
- `status` (string, optional) — https status code

### 405 Method Not Allowed Error

Method Not Allowed

- `code` (string, optional) — The code which categorize the https error, to compile recognize at application, i.e. CC00003,CC00004,CC00005 etc
- `error_details` (list of ErrorDetail, optional)
- `message` (string, optional) — message for error
- `ref_id` (string, optional) — unique reference ID for a particular request
- `status` (string, optional) — https status code

### 415 Unsupported Media Type Error

Unsupported Media Type

- `code` (string, optional) — The code which categorize the https error, to compile recognize at application, i.e. CC00003,CC00004,CC00005 etc
- `error_details` (list of ErrorDetail, optional)
- `message` (string, optional) — message for error
- `ref_id` (string, optional) — unique reference ID for a particular request
- `status` (string, optional) — https status code

### 500 Internal Server Error

Internal Server Error

- `code` (string, optional) — The code which categorize the https error, to compile recognize at application, i.e. CC00003,CC00004,CC00005 etc
- `error_details` (list of ErrorDetail, optional)
- `message` (string, optional) — message for error
- `ref_id` (string, optional) — unique reference ID for a particular request
- `status` (string, optional) — https status code

## Types

### Account

- `balance_control_option` (string, required) — Mandatory parameter only if value of 'action' parameter is 'activation'.Default options as below: Option will be defaulted from reporting virtual account if any. OR Full pool balance if the Virtual Account is reporting to virtual header account. If Purpose of Virtual Account is 'C', then value allowed should be only 'O'. Description of possible parameter values:O: Own Balance - Virtual Account to be able to use its own balance only. F: Full pool balance - Virtual Account to have access to full pool balance. X: Fixed Amount from pool - Fixed amount that a Virtual Account can withdraw from the pool over and above its own balance.
- `purpose_of_virtual_account` (string, required) — Mandatory parameter only if value of 'action' parameter is 'activation'.It specifies the purpose for creation of virtual account. Description of possible parameter values:\<b>P - Physical Account Owner. \<b>S - Client Subsidiary. \<b>C - Client's Customer.
- `virtual_account_balance_display_option` (string, required) — Mandatory parameter only if value of 'action' parameter is 'activation'.It specifies whether to display opening or closing balances or not. Default value will be 'N'.Description of possible parameter values:\<b>Y Show virtual account opening and closing balances. \<b>N Show ZERO opening and closing balance for virtual account in statements and reports.
- `virtual_account_number` (string, required) — Mandatory parameter only if the value of the 'action' parameter is 'activation'.It specifies the virtual account to be activated.
- `virtual_header_account` (string, required) — Physical account in a VAM structure.
- `address_line_1` (string, optional) — AddressLine-1 is to be provided by client, if purpose of VA is not P (Physical Account Owner). Information that locates and identifies a specific address, as defined by postal services, presented in free-form text.
- `address_line_2` (string, optional) — AddressLine-2 is to be provided by client, if purpose of VA is not P(Physical Account Owner). Information that locates and identifies a specific address, as defined by postal services, presented in free-form text.
- `address_line_3` (string, optional) — AddressLine-3 is to be provided by client, if purpose of VA is not P(Physical Account Owner). Information that locates and identifies a specific address, as defined by postal services, presented in free-form text.
- `address_line_4` (string, optional) — AddressLine-4 is to be provided by client, if purpose of VA is not P(Physical Account Owner). Information that locates and identifies a specific address, as defined by postal services, presented in free-form text.
- `alternate_account_number` (string, optional) — Alternate account number associated with virtual header account.
- `file_export_template_ids` (string, optional) — provide comma separated fileExport TemplateIds
- `fixed_amount` (string, optional) — Should be mandatory for virtual accounts if the balance control option is 'X' (balanceControlOption parameter value).
- `iban` (string, optional) — >- International Bank Account Number (IBAN) - identifier used internationally by financial institutions to uniquely identify the account of a customer. Further specifications of the format and content of the IBAN can be found in the standard ISO 13616 "Banking and related financial services - International Bank Account Number (IBAN)" version 1997-10-01, or later revisions.
- `name` (string, optional) — Name is to be provided by client, if purpose of VA is not P (Physical Account Owner).
- `reporting_account_number` (string, optional) — Reporting Account Number associated with virtual header account.
- `tax_identification_number` (string, optional) — Tax Identification Number of the account holder.

### ErrorDetail

- `action` (string, optional) — corrective action to be taken to resolve above issue
- `issue` (string, optional) — more details about the issue

## Examples

**Request**

```json
{
  "action": "reservation",
  "api_version": "string",
  "branch_code": "string",
  "contact_email": "string",
  "contact_first_name": "string",
  "contact_last_name": "string",
  "contact_phone": "string",
  "virtual_header_account": "string"
}
```

**Response**

```json
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><VirtualAccountResponse><RequestId>79e6fe44-6bbb-423f-a9e7-f9b3ee273307</RequestId><Status>success</Status><Message>Request accepted Successfully</Message></VirtualAccountResponse>"
```

**SDK Code**

```python virtualAccountActivateOrReserve_example (application/xml)
import requests

url = "https://tts.sandbox.apib2b.citi.com/citiconnect/sb/receivablesservices/v1/virtualaccount/activateorreserve"

payload = {
    "action": "reservation",
    "api_version": "string",
    "branch_code": "string",
    "contact_email": "string",
    "contact_first_name": "string",
    "contact_last_name": "string",
    "contact_phone": "string",
    "virtual_header_account": "string"
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript virtualAccountActivateOrReserve_example (application/xml)
const url = 'https://tts.sandbox.apib2b.citi.com/citiconnect/sb/receivablesservices/v1/virtualaccount/activateorreserve';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"action":"reservation","api_version":"string","branch_code":"string","contact_email":"string","contact_first_name":"string","contact_last_name":"string","contact_phone":"string","virtual_header_account":"string"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go virtualAccountActivateOrReserve_example (application/xml)
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://tts.sandbox.apib2b.citi.com/citiconnect/sb/receivablesservices/v1/virtualaccount/activateorreserve"

	payload := strings.NewReader("{\n  \"action\": \"reservation\",\n  \"api_version\": \"string\",\n  \"branch_code\": \"string\",\n  \"contact_email\": \"string\",\n  \"contact_first_name\": \"string\",\n  \"contact_last_name\": \"string\",\n  \"contact_phone\": \"string\",\n  \"virtual_header_account\": \"string\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby virtualAccountActivateOrReserve_example (application/xml)
require 'uri'
require 'net/http'

url = URI("https://tts.sandbox.apib2b.citi.com/citiconnect/sb/receivablesservices/v1/virtualaccount/activateorreserve")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"action\": \"reservation\",\n  \"api_version\": \"string\",\n  \"branch_code\": \"string\",\n  \"contact_email\": \"string\",\n  \"contact_first_name\": \"string\",\n  \"contact_last_name\": \"string\",\n  \"contact_phone\": \"string\",\n  \"virtual_header_account\": \"string\"\n}"

response = http.request(request)
puts response.read_body
```

```java virtualAccountActivateOrReserve_example (application/xml)
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://tts.sandbox.apib2b.citi.com/citiconnect/sb/receivablesservices/v1/virtualaccount/activateorreserve")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"action\": \"reservation\",\n  \"api_version\": \"string\",\n  \"branch_code\": \"string\",\n  \"contact_email\": \"string\",\n  \"contact_first_name\": \"string\",\n  \"contact_last_name\": \"string\",\n  \"contact_phone\": \"string\",\n  \"virtual_header_account\": \"string\"\n}")
  .asString();
```

```php virtualAccountActivateOrReserve_example (application/xml)
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://tts.sandbox.apib2b.citi.com/citiconnect/sb/receivablesservices/v1/virtualaccount/activateorreserve', [
  'body' => '{
  "action": "reservation",
  "api_version": "string",
  "branch_code": "string",
  "contact_email": "string",
  "contact_first_name": "string",
  "contact_last_name": "string",
  "contact_phone": "string",
  "virtual_header_account": "string"
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp virtualAccountActivateOrReserve_example (application/xml)
using RestSharp;

var client = new RestClient("https://tts.sandbox.apib2b.citi.com/citiconnect/sb/receivablesservices/v1/virtualaccount/activateorreserve");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"action\": \"reservation\",\n  \"api_version\": \"string\",\n  \"branch_code\": \"string\",\n  \"contact_email\": \"string\",\n  \"contact_first_name\": \"string\",\n  \"contact_last_name\": \"string\",\n  \"contact_phone\": \"string\",\n  \"virtual_header_account\": \"string\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift virtualAccountActivateOrReserve_example (application/xml)
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "action": "reservation",
  "api_version": "string",
  "branch_code": "string",
  "contact_email": "string",
  "contact_first_name": "string",
  "contact_last_name": "string",
  "contact_phone": "string",
  "virtual_header_account": "string"
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://tts.sandbox.apib2b.citi.com/citiconnect/sb/receivablesservices/v1/virtualaccount/activateorreserve")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```