Skip to main content

Simulated NetSuite Posting

Post the previewed records to the simulated NetSuite sandbox, keep the run in a posting log, and read the 20 latest runs or one run with per-record results.

POST /v1/ap/netsuite/post writes to a simulated sandbox log only. It does not call NetSuite, creates no bill in any NetSuite account, and nothing leaves the platform. The sandbox answers each record the way NetSuite's REST API answers a created record, so the result shows what a real posting would return.

Posting takes the records of the preview, posts them to the sandbox and keeps the run in the posting log. The sandbox answers each record with status 204 and a Location. Internal ids derive from the external id, so a repeated posting of the same bill gets the same internal id. Duplicate bills are never posted, not even with include_held; other held bills post only with include_held, flagged as on payment hold with approval pending.

With dry_run the run is computed and not stored, and its id is dry-run. The body is optional. The call needs the write scope and a key whose person is a member or above; the run is recorded with the key as its actor. It returns 201 with the run.

POST/v1/ap/netsuite/post

Body fields (all optional)

include_heldbooleanPost held bills (other than duplicates) on payment hold.
dry_runbooleanCompute the run and do not store it. Its id is dry-run.
limitintegerPost at most this many records, 1 to 5000.
entitystringOnly this entity's bills (its code, up to 200 characters). An empty string selects bills with no entity.

Response fields (the run)

id / adapter / created_atstringThe run id (a UUID, or dry-run), the adapter (netsuite) and the time.
records / amountinteger / numberRecords posted and their total amount.
include_heldbooleanWhether held bills were included.
actorstring | nullWho ran it, as kind:id.
results[]arrayPer record: bill_key, external_id, internal_id, status (204), location and payment_hold.
skipped[]arrayBills left out: bill_key, invoice_number, vendor and the reason.
log[]string[]The sandbox log lines of the run.

cURL: Post held and ready bills of one entity

curl -X POST "https://api.talonic.com/v1/ap/netsuite/post" \
  -H "Authorization: Bearer $TALONIC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"include_held": true, "entity": "US01", "limit": 100}'

Response: 201 The run (abridged)

{
  "id": "e1b47c0a-5f20-4c7e-8a9d-0b6d3c72f518",
  "adapter": "netsuite",
  "created_at": "2026-10-21T09:30:12.000Z",
  "records": 1,
  "amount": 18450,
  "include_held": true,
  "actor": "app:api:2f7a",
  "results": [
    { "bill_key": "bill-0001", "external_id": "bill-0001", "internal_id": "100231", "status": 204, "location": "/services/rest/record/v1/vendorBill/100231", "payment_hold": true }
  ],
  "skipped": [],
  "log": ["POST /services/rest/record/v1/vendorBill bill-0001 -> 204"]
}

The Posting Log

GET /v1/ap/netsuite/runs returns the 20 most recent runs of the simulated sandbox, newest first, as summaries without the per-record results. GET /v1/ap/netsuite/runs/{id} returns one run with its per-record results, the bills it skipped and its log; the id must be a UUID, and an unknown run is 404. Dry runs are not stored and therefore not in the log. Both routes need the read scope.

GET/v1/ap/netsuite/runs

Response fields (data[])

id / adapter / created_atstringThe run id, the adapter (netsuite) and the time.
records / amountinteger / numberRecords posted and their total amount.
include_held / actorboolean / stringWhether held bills were included, and who ran it.
GET/v1/ap/netsuite/runs/{id}

Path parameters

id*uuidThe run id from the posting log.

After a real run, sandbox_id on a bill from GET /v1/ap/bills carries the internal id the sandbox gave it on the latest run, and last_run on the overview summarizes the run.

Frequently asked questions

Is anything sent to NetSuite when I post?+
No. The post route writes to a simulated sandbox log inside the platform. No NetSuite account is contacted and no bill is created there. The result shows how NetSuite's REST API answers a created record: status 204 with a Location.
What happens if I post the same bill twice?+
The sandbox derives the internal id from the external id, so the same bill gets the same internal id on every run. Each real run is still stored as its own entry in the posting log.
Can duplicates be posted with include_held?+
No. Duplicate bills are never posted. include_held adds the other held bills, and they post flagged as on payment hold with approval pending.