Accounting
curl --request POST \
--url https://win.oneshotagent.com/v1/tools/ledger/invoicesimport requests
url = "https://win.oneshotagent.com/v1/tools/ledger/invoices"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://win.oneshotagent.com/v1/tools/ledger/invoices', 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://win.oneshotagent.com/v1/tools/ledger/invoices",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://win.oneshotagent.com/v1/tools/ledger/invoices"
req, _ := http.NewRequest("POST", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://win.oneshotagent.com/v1/tools/ledger/invoices")
.asString();require 'uri'
require 'net/http'
url = URI("https://win.oneshotagent.com/v1/tools/ledger/invoices")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
response = http.request(request)
puts response.read_body{
"data.records": [
{}
],
"data.next_cursor": "<string>"
}Connections
Accounting
Read invoices, bills and reports from your connected accounting system
POST
/
v1
/
tools
/
ledger
/
invoices
Accounting
curl --request POST \
--url https://win.oneshotagent.com/v1/tools/ledger/invoicesimport requests
url = "https://win.oneshotagent.com/v1/tools/ledger/invoices"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://win.oneshotagent.com/v1/tools/ledger/invoices', 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://win.oneshotagent.com/v1/tools/ledger/invoices",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://win.oneshotagent.com/v1/tools/ledger/invoices"
req, _ := http.NewRequest("POST", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://win.oneshotagent.com/v1/tools/ledger/invoices")
.asString();require 'uri'
require 'net/http'
url = URI("https://win.oneshotagent.com/v1/tools/ledger/invoices")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
response = http.request(request)
puts response.read_body{
"data.records": [
{}
],
"data.next_cursor": "<string>"
}Overview
Read-only tools on a connected QuickBooks, Zoho Books or Xero (Connections). Nothing is written at the system; nothing fetched is kept.POST /v1/tools/ledger/invoices(ledger_invoices): invoices you issued.POST /v1/tools/ledger/bills(ledger_bills): bills you owe.POST /v1/tools/ledger/reports(ledger_reports): a balance sheet, profit and loss or trial balance.
connection_id: list your connections (GET /v1/connections) and pick by system and account_label.
Xero: a page can hold fewer than limit records. A sign-in reaching several organisations reads the one named in account_label.
Authentication
Requires x402 payment in thepayment-signature header. Refusals for the body, the connection or an unavailable system come before payment and are not charged.
Invoices and bills
| Field | Meaning |
|---|---|
connection_id | Required. The connection to read. |
from, to | Records issued from, and up to, this date (YYYY-MM-DD). |
status | open, paid, overdue or all (default). |
counterparty | Only records whose customer or vendor name contains this text. |
limit | Records per page, 1 to 100, default 25. |
cursor | The next_cursor of the previous page. |
{ "connection_id": "5f4a3b2c-1d0e-4f9a-8b7c-6d5e4f3a2b1c", "status": "open", "limit": 25 }
Response (200)
array
Each record:
id, number, counterparty (name, id), issued_on, due_on, status (open, paid, overdue, void or draft), currency, total, balance and source (system, id). Missing fields are null.string
Present when more records exist: send it as
cursor.Reports
| Field | Meaning |
|---|---|
connection_id | Required. The connection to read. |
type | Required. balance_sheet, profit_and_loss or trial_balance. |
as_of | Balance sheet and trial balance: the date the report stands at (YYYY-MM-DD). QuickBooks and Xero. |
from, to | Profit and loss: the first and last day of the period. |
limit, cursor | Rows per page, and the next page. |
currency null). Zoho Books serves the trial balance as of today only.
Response (200)
{
"success": true,
"data": {
"type": "balance_sheet",
"period": { "as_of": "2026-09-30" },
"currency": "USD",
"rows": [{ "account": "Checking", "account_id": "35", "amount": 12480.5 }],
"source": { "system": "quickbooks", "id": "BalanceSheet" }
}
}
Errors
| Status | Error | Meaning |
|---|---|---|
| 400 | invalid_request | The body is not valid. |
| 400 | unsupported_for_system | The system does not offer this report or input, such as a Xero profit and loss over 365 days. |
| 400 | connection_wrong_system | The connection is not on an accounting system. |
| 400 | not_supported | Too many counterparty matches (narrow it), or a Xero sign-in reaching several organisations (connect one). A paid call is returned as account credit. |
| 404 | connection_not_found | No such connection for this agent. |
| 409 | connection_expired, connection_revoked, connection_not_active | Reconnect from the console, or start a new connection. |
| 503 | not_configured | The system is not available right now. |
| 503 | rate_limited, system_unavailable | The system is busy or did not answer; a paid call is returned as account credit. |