curl --request POST \
--url https://api.arcuserp.com/v1/bank-accounts \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"gl_account_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"institution": "<string>",
"is_ap_account": true,
"deposit_layout": {}
}
'import requests
url = "https://api.arcuserp.com/v1/bank-accounts"
payload = {
"name": "<string>",
"gl_account_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"institution": "<string>",
"is_ap_account": True,
"deposit_layout": {}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: '<string>',
gl_account_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
institution: '<string>',
is_ap_account: true,
deposit_layout: {}
})
};
fetch('https://api.arcuserp.com/v1/bank-accounts', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.arcuserp.com/v1/bank-accounts",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => '<string>',
'gl_account_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'institution' => '<string>',
'is_ap_account' => true,
'deposit_layout' => [
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.arcuserp.com/v1/bank-accounts"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"gl_account_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"institution\": \"<string>\",\n \"is_ap_account\": true,\n \"deposit_layout\": {}\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(string(body))
}HttpResponse<String> response = Unirest.post("https://api.arcuserp.com/v1/bank-accounts")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"gl_account_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"institution\": \"<string>\",\n \"is_ap_account\": true,\n \"deposit_layout\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.arcuserp.com/v1/bank-accounts")
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 \"name\": \"<string>\",\n \"gl_account_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"institution\": \"<string>\",\n \"is_ap_account\": true,\n \"deposit_layout\": {}\n}"
response = http.request(request)
puts response.read_body{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"entity_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"gl_account_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"gl_account_number": "<string>",
"gl_account_name": "<string>",
"name": "<string>",
"institution": "<string>",
"account_type": "checking",
"account_number_last4": "<string>",
"is_active": true,
"is_ap_account": true,
"current_balance": 123,
"last_synced_at": "2023-11-07T05:31:56Z",
"sync_status": "<string>",
"has_feed": true,
"deposit_layout": {},
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z"
}{
"error": "not_found",
"code": "not_found",
"type": "not_found",
"hint": "The requested order does not exist or does not belong to this entity.",
"param": "expand[0]",
"required": "accounts:read",
"request_id": "req_abc123"
}{
"error": "not_found",
"code": "not_found",
"type": "not_found",
"hint": "The requested order does not exist or does not belong to this entity.",
"param": "expand[0]",
"required": "accounts:read",
"request_id": "req_abc123"
}{
"error": "not_found",
"code": "not_found",
"type": "not_found",
"hint": "The requested order does not exist or does not belong to this entity.",
"param": "expand[0]",
"required": "accounts:read",
"request_id": "req_abc123"
}Create a bank account
Creates a bank account linked to an existing GL account; Plaid connection fields are ignored here and are managed separately through the Plaid connector in Settings > Integrations. Requires accounting:write scope.
curl --request POST \
--url https://api.arcuserp.com/v1/bank-accounts \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"gl_account_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"institution": "<string>",
"is_ap_account": true,
"deposit_layout": {}
}
'import requests
url = "https://api.arcuserp.com/v1/bank-accounts"
payload = {
"name": "<string>",
"gl_account_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"institution": "<string>",
"is_ap_account": True,
"deposit_layout": {}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: '<string>',
gl_account_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
institution: '<string>',
is_ap_account: true,
deposit_layout: {}
})
};
fetch('https://api.arcuserp.com/v1/bank-accounts', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.arcuserp.com/v1/bank-accounts",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => '<string>',
'gl_account_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'institution' => '<string>',
'is_ap_account' => true,
'deposit_layout' => [
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.arcuserp.com/v1/bank-accounts"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"gl_account_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"institution\": \"<string>\",\n \"is_ap_account\": true,\n \"deposit_layout\": {}\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(string(body))
}HttpResponse<String> response = Unirest.post("https://api.arcuserp.com/v1/bank-accounts")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"gl_account_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"institution\": \"<string>\",\n \"is_ap_account\": true,\n \"deposit_layout\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.arcuserp.com/v1/bank-accounts")
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 \"name\": \"<string>\",\n \"gl_account_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"institution\": \"<string>\",\n \"is_ap_account\": true,\n \"deposit_layout\": {}\n}"
response = http.request(request)
puts response.read_body{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"entity_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"gl_account_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"gl_account_number": "<string>",
"gl_account_name": "<string>",
"name": "<string>",
"institution": "<string>",
"account_type": "checking",
"account_number_last4": "<string>",
"is_active": true,
"is_ap_account": true,
"current_balance": 123,
"last_synced_at": "2023-11-07T05:31:56Z",
"sync_status": "<string>",
"has_feed": true,
"deposit_layout": {},
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z"
}{
"error": "not_found",
"code": "not_found",
"type": "not_found",
"hint": "The requested order does not exist or does not belong to this entity.",
"param": "expand[0]",
"required": "accounts:read",
"request_id": "req_abc123"
}{
"error": "not_found",
"code": "not_found",
"type": "not_found",
"hint": "The requested order does not exist or does not belong to this entity.",
"param": "expand[0]",
"required": "accounts:read",
"request_id": "req_abc123"
}{
"error": "not_found",
"code": "not_found",
"type": "not_found",
"hint": "The requested order does not exist or does not belong to this entity.",
"param": "expand[0]",
"required": "accounts:read",
"request_id": "req_abc123"
}Authorizations
API key issued per entity via Settings > Developers > API Keys.
Each key carries scopes (e.g. orders:read, products:write).
Bearer token format: Authorization: Bearer ark_live_ent_
Test keys use ark_test_ent_. Both are issued per entity
via Settings > Developers > API Keys.
Body
Response
Created bank account
A bank account linked to a GL account. Used for bank reconciliation and Plaid-based transaction sync. Plaid fields are read-only and managed by routes/plaid.mjs exclusively. Verified against live dev RDS accounting.bank_accounts.
Immutable post-create
checking, savings, credit, loan, other Plaid-synced balance
True when this account's activity arrives by itself: it is mapped to a connected bank feed AND that login still resolves. Both halves are required, because a mapped account whose login was removed stops producing lines. Added 2026-09-19 (lane W4-B); it is what lets a transfer counterparty picker tell an account whose other leg will arrive on its own from one where the line in hand is the only record the movement will ever produce.
Was this page helpful?

