Push one journal to a ledger connection
curl --request POST \
--url https://api.range.org/v2/account-connections/bookkeeping/{connectionId}/journals \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: <api-key>' \
--data '
{
"date": "2026-10-01",
"narration": "0xaaa interest payment",
"lines": [
{
"account_external_id": "c4f29c22-28c2-4a13-9eab-ecbbd641ffdf",
"amount": "100.00",
"side": "debit",
"description": "interest payment"
}
],
"external_id": "d312dd5e-a53e-46d1-9d51-c569ef4570b7"
}
'import requests
url = "https://api.range.org/v2/account-connections/bookkeeping/{connectionId}/journals"
payload = {
"date": "2026-10-01",
"narration": "0xaaa interest payment",
"lines": [
{
"account_external_id": "c4f29c22-28c2-4a13-9eab-ecbbd641ffdf",
"amount": "100.00",
"side": "debit",
"description": "interest payment"
}
],
"external_id": "d312dd5e-a53e-46d1-9d51-c569ef4570b7"
}
headers = {
"X-API-KEY": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-KEY': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
date: '2026-10-01',
narration: '0xaaa interest payment',
lines: [
{
account_external_id: 'c4f29c22-28c2-4a13-9eab-ecbbd641ffdf',
amount: '100.00',
side: 'debit',
description: 'interest payment'
}
],
external_id: 'd312dd5e-a53e-46d1-9d51-c569ef4570b7'
})
};
fetch('https://api.range.org/v2/account-connections/bookkeeping/{connectionId}/journals', 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.range.org/v2/account-connections/bookkeeping/{connectionId}/journals",
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([
'date' => '2026-10-01',
'narration' => '0xaaa interest payment',
'lines' => [
[
'account_external_id' => 'c4f29c22-28c2-4a13-9eab-ecbbd641ffdf',
'amount' => '100.00',
'side' => 'debit',
'description' => 'interest payment'
]
],
'external_id' => 'd312dd5e-a53e-46d1-9d51-c569ef4570b7'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-KEY: <api-key>"
],
]);
$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.range.org/v2/account-connections/bookkeeping/{connectionId}/journals"
payload := strings.NewReader("{\n \"date\": \"2026-10-01\",\n \"narration\": \"0xaaa interest payment\",\n \"lines\": [\n {\n \"account_external_id\": \"c4f29c22-28c2-4a13-9eab-ecbbd641ffdf\",\n \"amount\": \"100.00\",\n \"side\": \"debit\",\n \"description\": \"interest payment\"\n }\n ],\n \"external_id\": \"d312dd5e-a53e-46d1-9d51-c569ef4570b7\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-KEY", "<api-key>")
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.range.org/v2/account-connections/bookkeeping/{connectionId}/journals")
.header("X-API-KEY", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"date\": \"2026-10-01\",\n \"narration\": \"0xaaa interest payment\",\n \"lines\": [\n {\n \"account_external_id\": \"c4f29c22-28c2-4a13-9eab-ecbbd641ffdf\",\n \"amount\": \"100.00\",\n \"side\": \"debit\",\n \"description\": \"interest payment\"\n }\n ],\n \"external_id\": \"d312dd5e-a53e-46d1-9d51-c569ef4570b7\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.range.org/v2/account-connections/bookkeeping/{connectionId}/journals")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-KEY"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"date\": \"2026-10-01\",\n \"narration\": \"0xaaa interest payment\",\n \"lines\": [\n {\n \"account_external_id\": \"c4f29c22-28c2-4a13-9eab-ecbbd641ffdf\",\n \"amount\": \"100.00\",\n \"side\": \"debit\",\n \"description\": \"interest payment\"\n }\n ],\n \"external_id\": \"d312dd5e-a53e-46d1-9d51-c569ef4570b7\"\n}"
response = http.request(request)
puts response.read_body{
"external_id": "d312dd5e-a53e-46d1-9d51-c569ef4570b7",
"status": "draft"
}Account Connections
Push a bookkeeping journal
Create or update a balanced journal in a linked bookkeeping system.
POST
/
v2
/
account-connections
/
bookkeeping
/
{connectionId}
/
journals
Push one journal to a ledger connection
curl --request POST \
--url https://api.range.org/v2/account-connections/bookkeeping/{connectionId}/journals \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: <api-key>' \
--data '
{
"date": "2026-10-01",
"narration": "0xaaa interest payment",
"lines": [
{
"account_external_id": "c4f29c22-28c2-4a13-9eab-ecbbd641ffdf",
"amount": "100.00",
"side": "debit",
"description": "interest payment"
}
],
"external_id": "d312dd5e-a53e-46d1-9d51-c569ef4570b7"
}
'import requests
url = "https://api.range.org/v2/account-connections/bookkeeping/{connectionId}/journals"
payload = {
"date": "2026-10-01",
"narration": "0xaaa interest payment",
"lines": [
{
"account_external_id": "c4f29c22-28c2-4a13-9eab-ecbbd641ffdf",
"amount": "100.00",
"side": "debit",
"description": "interest payment"
}
],
"external_id": "d312dd5e-a53e-46d1-9d51-c569ef4570b7"
}
headers = {
"X-API-KEY": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-KEY': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
date: '2026-10-01',
narration: '0xaaa interest payment',
lines: [
{
account_external_id: 'c4f29c22-28c2-4a13-9eab-ecbbd641ffdf',
amount: '100.00',
side: 'debit',
description: 'interest payment'
}
],
external_id: 'd312dd5e-a53e-46d1-9d51-c569ef4570b7'
})
};
fetch('https://api.range.org/v2/account-connections/bookkeeping/{connectionId}/journals', 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.range.org/v2/account-connections/bookkeeping/{connectionId}/journals",
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([
'date' => '2026-10-01',
'narration' => '0xaaa interest payment',
'lines' => [
[
'account_external_id' => 'c4f29c22-28c2-4a13-9eab-ecbbd641ffdf',
'amount' => '100.00',
'side' => 'debit',
'description' => 'interest payment'
]
],
'external_id' => 'd312dd5e-a53e-46d1-9d51-c569ef4570b7'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-KEY: <api-key>"
],
]);
$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.range.org/v2/account-connections/bookkeeping/{connectionId}/journals"
payload := strings.NewReader("{\n \"date\": \"2026-10-01\",\n \"narration\": \"0xaaa interest payment\",\n \"lines\": [\n {\n \"account_external_id\": \"c4f29c22-28c2-4a13-9eab-ecbbd641ffdf\",\n \"amount\": \"100.00\",\n \"side\": \"debit\",\n \"description\": \"interest payment\"\n }\n ],\n \"external_id\": \"d312dd5e-a53e-46d1-9d51-c569ef4570b7\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-KEY", "<api-key>")
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.range.org/v2/account-connections/bookkeeping/{connectionId}/journals")
.header("X-API-KEY", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"date\": \"2026-10-01\",\n \"narration\": \"0xaaa interest payment\",\n \"lines\": [\n {\n \"account_external_id\": \"c4f29c22-28c2-4a13-9eab-ecbbd641ffdf\",\n \"amount\": \"100.00\",\n \"side\": \"debit\",\n \"description\": \"interest payment\"\n }\n ],\n \"external_id\": \"d312dd5e-a53e-46d1-9d51-c569ef4570b7\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.range.org/v2/account-connections/bookkeeping/{connectionId}/journals")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-KEY"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"date\": \"2026-10-01\",\n \"narration\": \"0xaaa interest payment\",\n \"lines\": [\n {\n \"account_external_id\": \"c4f29c22-28c2-4a13-9eab-ecbbd641ffdf\",\n \"amount\": \"100.00\",\n \"side\": \"debit\",\n \"description\": \"interest payment\"\n }\n ],\n \"external_id\": \"d312dd5e-a53e-46d1-9d51-c569ef4570b7\"\n}"
response = http.request(request)
puts response.read_body{
"external_id": "d312dd5e-a53e-46d1-9d51-c569ef4570b7",
"status": "draft"
}- Xero saves a draft manual journal, which does not move balances until it is posted in Xero. QuickBooks posts the journal immediately.
- Pass
external_idfrom a previous response to update that journal instead of creating another. - Reconnect a Xero connection authorized before journal writes were added so its token includes the write scope.
Authorizations
AuthorizationAuthorization
Authorization method required to allow user to access the api endpoints.
Path Parameters
Resource identifier.
Example:
"550e8400-e29b-41d4-a716-446655440000"
Body
application/json
Example:
"2026-10-01"
Journal narration. For a movement, the hash and the note.
Maximum string length:
255Example:
"0xaaa interest payment"
Show child attributes
Show child attributes
Provider journal id from a previous push. When set, that journal is updated.
Maximum string length:
64Example:
"d312dd5e-a53e-46d1-9d51-c569ef4570b7"
Response
200 - application/json
Provider journal id. Send it back as external_id to update.
Example:
"d312dd5e-a53e-46d1-9d51-c569ef4570b7"
Xero returns draft. QuickBooks returns posted, because a QuickBooks journal entry hits the books on create.
Available options:
draft, posted Example:
"draft"
Last modified on November 10, 2026
Was this page helpful?