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

# Create account

POST https://api.haloinvest.ng/api/banking/account/create-account
Content-Type: application/json

Opens an account for a customer from their BVN. Halo checks the BVN with the bank, and the phone number you send must match the phone number on the BVN record. The customer's names are taken from the BVN record.

Each customer can hold one account with your business. If the customer already has one, it is returned.

When the bank is still opening the account the answer is 202. Call again with the same details to get the account; no second account is opened.

The customer is returned as `user.id` only.

Reference: https://docs.haloinvest.ng/api-reference/accounts/create-account

## Authentication

- `Authorization` header (bearer token, required) — Your Halo partner API key, sent as `Authorization: Bearer <key>`.

## Request

### Body (application/json)

This endpoint expects an object.

- `BVN` (string, required) — The customer's Bank Verification Number.
- `PhoneNo` (string, required) — Must match the phone number on the BVN record.
- `Email` (string, required) — The customer's email address.
- `LastName` (string, required) — The customer's last name. The name on the BVN record is used.
- `OtherNames` (string, required) — The customer's other names. The names on the BVN record are used.
- `isVirtual` (boolean, required) — Set to true to link the account to your business pool account.
- `FirstName` (string, optional, nullable) — The customer's first name. The name on the BVN record is used.
- `FullName` (string, optional, nullable) — The customer's full name.
- `NationalIdentityNo` (string, optional, nullable) — The customer's NIN.
- `Gender` (string, optional, nullable) — The customer's gender.
- `AccountName` (string, optional, nullable) — The name on the account.

## Response

### 200

The account is open.

- `status` (boolean, required) — True on success, false otherwise.
- `message` (EnvelopeMessage, required) — A short message. On a 422 validation failure it is an object of field names to error lists.
- `status_code` (integer, required) — The HTTP status code.
- `data` (any, optional) — The result. Left out on most errors.

### 202

The bank is still opening the account. Call again with the same details.

- `status` (boolean, required) — True on success, false otherwise.
- `message` (EnvelopeMessage, required) — A short message. On a 422 validation failure it is an object of field names to error lists.
- `status_code` (integer, required) — The HTTP status code.
- `data` (any, optional) — The result. Left out on most errors.

## Errors

### 400 Bad Request Error

The BVN check failed, the phone number does not match the BVN, or the bank refused the account.

- `status` (boolean, required) — True on success, false otherwise.
- `message` (EnvelopeMessage, required) — A short message. On a 422 validation failure it is an object of field names to error lists.
- `status_code` (integer, required) — The HTTP status code.
- `data` (any, optional) — The result. Left out on most errors.

### 401 Unauthorized Error

The API key is missing or not recognised, or your business is switched off.

- `error` (UnauthorizedErrorError, optional)

### 422 Unprocessable Entity Error

The request failed validation. `message` lists the errors by field.

- `status` (boolean, required) — True on success, false otherwise.
- `message` (EnvelopeMessage, required) — A short message. On a 422 validation failure it is an object of field names to error lists.
- `status_code` (integer, required) — The HTTP status code.
- `data` (any, optional) — The result. Left out on most errors.

### 429 Too Many Requests Error

Too many requests. Wait and try again.

- `status` (boolean, required) — True on success, false otherwise.
- `message` (EnvelopeMessage, required) — A short message. On a 422 validation failure it is an object of field names to error lists.
- `status_code` (integer, required) — The HTTP status code.
- `data` (any, optional) — The result. Left out on most errors.

## Types

### EnvelopeMessage

A short message. On a 422 validation failure it is an object of field names to error lists.

- string
- map from string to list of string

### UnauthorizedErrorError

- `message` (string, optional)

## Examples

### Accounts_createAccount_example

**Request**

```json
{
  "BVN": "22200000001",
  "PhoneNo": "08000000001",
  "Email": "ada@example.com",
  "LastName": "Example",
  "OtherNames": "Ada",
  "isVirtual": false
}
```

**Response**

```json
{
  "status": true,
  "message": "Request Successful",
  "status_code": 200,
  "data": null
}
```

**SDK Code**

```python Accounts_createAccount_example
import requests

url = "https://api.haloinvest.ng/api/banking/account/create-account"

payload = {
    "BVN": "22200000001",
    "PhoneNo": "08000000001",
    "Email": "ada@example.com",
    "LastName": "Example",
    "OtherNames": "Ada",
    "isVirtual": False
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

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

print(response.json())
```

```javascript Accounts_createAccount_example
const url = 'https://api.haloinvest.ng/api/banking/account/create-account';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"BVN":"22200000001","PhoneNo":"08000000001","Email":"ada@example.com","LastName":"Example","OtherNames":"Ada","isVirtual":false}'
};

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

```go Accounts_createAccount_example
package main

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

func main() {

	url := "https://api.haloinvest.ng/api/banking/account/create-account"

	payload := strings.NewReader("{\n  \"BVN\": \"22200000001\",\n  \"PhoneNo\": \"08000000001\",\n  \"Email\": \"ada@example.com\",\n  \"LastName\": \"Example\",\n  \"OtherNames\": \"Ada\",\n  \"isVirtual\": false\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 Accounts_createAccount_example
require 'uri'
require 'net/http'

url = URI("https://api.haloinvest.ng/api/banking/account/create-account")

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  \"BVN\": \"22200000001\",\n  \"PhoneNo\": \"08000000001\",\n  \"Email\": \"ada@example.com\",\n  \"LastName\": \"Example\",\n  \"OtherNames\": \"Ada\",\n  \"isVirtual\": false\n}"

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

```java Accounts_createAccount_example
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.haloinvest.ng/api/banking/account/create-account")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"BVN\": \"22200000001\",\n  \"PhoneNo\": \"08000000001\",\n  \"Email\": \"ada@example.com\",\n  \"LastName\": \"Example\",\n  \"OtherNames\": \"Ada\",\n  \"isVirtual\": false\n}")
  .asString();
```

```php Accounts_createAccount_example
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.haloinvest.ng/api/banking/account/create-account', [
  'body' => '{
  "BVN": "22200000001",
  "PhoneNo": "08000000001",
  "Email": "ada@example.com",
  "LastName": "Example",
  "OtherNames": "Ada",
  "isVirtual": false
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

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

```csharp Accounts_createAccount_example
using RestSharp;

var client = new RestClient("https://api.haloinvest.ng/api/banking/account/create-account");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"BVN\": \"22200000001\",\n  \"PhoneNo\": \"08000000001\",\n  \"Email\": \"ada@example.com\",\n  \"LastName\": \"Example\",\n  \"OtherNames\": \"Ada\",\n  \"isVirtual\": false\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Accounts_createAccount_example
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "BVN": "22200000001",
  "PhoneNo": "08000000001",
  "Email": "ada@example.com",
  "LastName": "Example",
  "OtherNames": "Ada",
  "isVirtual": false
] as [String : Any]

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

let request = NSMutableURLRequest(url: NSURL(string: "https://api.haloinvest.ng/api/banking/account/create-account")! 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()
```

### Accounts_createAccount_example

**Request**

```json
{
  "BVN": "22200000001",
  "PhoneNo": "08000000001",
  "Email": "ada@example.com",
  "LastName": "Example",
  "OtherNames": "Ada",
  "isVirtual": false
}
```

**Response**

```json
{
  "status": false,
  "message": "The bank is still opening this account. Call create-account again with the same details to get it; no second account will be opened.",
  "status_code": 202,
  "data": null
}
```

**SDK Code**

```python Accounts_createAccount_example
import requests

url = "https://api.haloinvest.ng/api/banking/account/create-account"

payload = {
    "BVN": "22200000001",
    "PhoneNo": "08000000001",
    "Email": "ada@example.com",
    "LastName": "Example",
    "OtherNames": "Ada",
    "isVirtual": False
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

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

print(response.json())
```

```javascript Accounts_createAccount_example
const url = 'https://api.haloinvest.ng/api/banking/account/create-account';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"BVN":"22200000001","PhoneNo":"08000000001","Email":"ada@example.com","LastName":"Example","OtherNames":"Ada","isVirtual":false}'
};

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

```go Accounts_createAccount_example
package main

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

func main() {

	url := "https://api.haloinvest.ng/api/banking/account/create-account"

	payload := strings.NewReader("{\n  \"BVN\": \"22200000001\",\n  \"PhoneNo\": \"08000000001\",\n  \"Email\": \"ada@example.com\",\n  \"LastName\": \"Example\",\n  \"OtherNames\": \"Ada\",\n  \"isVirtual\": false\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 Accounts_createAccount_example
require 'uri'
require 'net/http'

url = URI("https://api.haloinvest.ng/api/banking/account/create-account")

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  \"BVN\": \"22200000001\",\n  \"PhoneNo\": \"08000000001\",\n  \"Email\": \"ada@example.com\",\n  \"LastName\": \"Example\",\n  \"OtherNames\": \"Ada\",\n  \"isVirtual\": false\n}"

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

```java Accounts_createAccount_example
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.haloinvest.ng/api/banking/account/create-account")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"BVN\": \"22200000001\",\n  \"PhoneNo\": \"08000000001\",\n  \"Email\": \"ada@example.com\",\n  \"LastName\": \"Example\",\n  \"OtherNames\": \"Ada\",\n  \"isVirtual\": false\n}")
  .asString();
```

```php Accounts_createAccount_example
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.haloinvest.ng/api/banking/account/create-account', [
  'body' => '{
  "BVN": "22200000001",
  "PhoneNo": "08000000001",
  "Email": "ada@example.com",
  "LastName": "Example",
  "OtherNames": "Ada",
  "isVirtual": false
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

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

```csharp Accounts_createAccount_example
using RestSharp;

var client = new RestClient("https://api.haloinvest.ng/api/banking/account/create-account");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"BVN\": \"22200000001\",\n  \"PhoneNo\": \"08000000001\",\n  \"Email\": \"ada@example.com\",\n  \"LastName\": \"Example\",\n  \"OtherNames\": \"Ada\",\n  \"isVirtual\": false\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Accounts_createAccount_example
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "BVN": "22200000001",
  "PhoneNo": "08000000001",
  "Email": "ada@example.com",
  "LastName": "Example",
  "OtherNames": "Ada",
  "isVirtual": false
] as [String : Any]

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

let request = NSMutableURLRequest(url: NSURL(string: "https://api.haloinvest.ng/api/banking/account/create-account")! 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()
```