Orders
Sales orders. One table serves several documents. ordertype is fulfillment, service or rental; status is quote, unconfirmed, open, partial or billed. A quote is status: "quote" - it is not an order type, and it wins over ordertype, so a service order that is still a quote is a quote. Converting a quote to an order is a PATCH of status to open, which commits inventory.
The object#
| Field | Type | Description |
|---|---|---|
| idread-only | integer | NolaPro id. |
| ordernumberread-only | integer | Equals id - set by the system immediately after insert, kept only for legacy joins. Not a sequence, not money (the column is a double for historical reasons), and never writable. The human-facing number is onum. |
| onum | string(30) | Display order number when it differs from the record id; imported orders keep their original numbers here. |
| ponumber | string(30) | The customer's purchase order number. |
| orderbycompanyid | integer | Orderbycompanyid. Id only. |
| shiptocompanyid | integer | Shiptocompanyid. Id only. |
| status | string | Where the document is in its life. A quote is a status, not an order type, and it wins over ordertype. Stored as int -1/-2/0/1/2; never exposed or accepted (D35). One of quote, unconfirmed, open, partial, billed. |
| customerbillcode | string(20) | Customer Bill Code printed on order documents. |
| pricelevelid | integer | Pricelevelid. Id only. |
| inventorylocationid | integer | Inventorylocationid. Id only. |
| inventorylocation | string(20) | The locationcode of the referenced inventorylocations, instead of the id. Send this or inventorylocationid, not both unless they agree. |
| cancel | boolean | Cancelled. Always a boolean on the wire, whatever integer width the column uses (D23). |
| entrydate | string | When the record was created. |
| duedate | string | Date payment is due. |
| lastchangedateread-only | string | Last modification. Drives modifiedsince. |
| payment_method | string(12) | Payment method text carried in from the web store order. |
| shipping_method | string(32) | Shipping method text carried in from the web store order. |
| orders_date_finished | string | Date the web store marked the order finished. |
| currency | string(10) | Currency the order is priced in. |
| transaction_idread-only | string(32) | Payment gateway reference. Read-only: written by the gateway, never by a caller. |
| customers_id | integer | Customer id in the osCommerce-style web store tables, for cart integrations. |
| customers | string(30) | The customercode of the referenced customers, instead of the id. Send this or customers_id, not both unless they agree. |
| shipping_costmoney | string(4dp) | Stored as decimal(19,4). |
| order_weightnumber | string(2dp) | Numeric string, 2 decimal places. Not money - do not apply currency rounding. |
| currency_valuenumber | string(6dp) | Numeric string, 6 decimal places. Not money - do not apply currency rounding. |
| wherefrom | string(100) | Module or channel that created the order; empty for orders entered in NolaPro. |
| confirmed_by | string(100) | Who confirmed the order. |
| confirmed_date | string(100) | Date the order was confirmed. |
| confirmed | string(100) | 1 once the order is confirmed with the customer. |
| paymeth | integer | Payment method: 1 = cash, 2 = check, 3 = credit card, 4 = ACH/EFT, 5 = card terminal; 0 = on account or unset. |
| ordertype | string | What kind of document this is. Stored as int 0/1/2; the integer is never exposed or accepted (D35). One of fulfillment, service, rental. |
| estimatemoney | string(4dp) | Stored as decimal(19,4). |
| depositmoney | string(4dp) | Stored as decimal(19,4). |
| salesmanid | integer | Reference to salesmen, by id. Write either this or salesman. |
| salesman | string(50) | The name of the referenced salesmen, instead of the id. Send this or salesmanid, not both unless they agree. |
| sales_categoriesid | integer | Sales category the order reports under. |
| sales_categories | string(50) | The description of the referenced salescategories, instead of the id. Send this or sales_categoriesid, not both unless they agree. |
| statusid | integer | Statusid. Id only. |
| rma_arorder_returnedid | integer | Rma arorder returnedid. Id only. |
| rma_orig_arorderid | integer | Rma orig arorderid. Id only. |
| carrierserviceid_preferred | integer | Carrier service the customer prefers for shipping this order. |
| finalship | integer | 1 when the order is Marked Final - no more shipments are expected. |
| curratenumber | string(10dp) | Numeric string, 10 decimal places. Not money - do not apply currency rounding. |
| arglaccountid | integer | Arglaccountid. Id only. |
| arglaccount | string(20) | The name of the referenced glaccounts, instead of the id. Send this or arglaccountid, not both unless they agree. |
| defaultworktypeid | integer | Reference to worktypes, by id. Write either this or defaultworktype. |
| defaultworktype | string(50) | The name of the referenced worktypes, instead of the id. Send this or defaultworktypeid, not both unless they agree. |
| jobid | integer | Jobid. Id only. |
| defaultworksubtypeid | integer | Defaultworksubtypeid. Id only. |
| stageid | integer | Stageid. Id only. |
| edi | integer | 1 when the order arrived through EDI. |
| costcodeid | integer | Cost code. |
| costcode | string(20) | Code for the referenced costcode, instead of the id. |
| outsidesalesmargin | integer | Margin percentage used for outside-sales commission on the order; -1 when the margin was overridden. |
| ediasn | integer | 1 once the EDI advance ship notice (ASN) has been sent for the order. |
| ediinvoice | integer | 1 once the invoice has been sent through EDI. |
| lastshipdateread-only | string | Date of the most recent shipment on the order. |
| defaultvendorid | integer | Reference to vendors, by id. Write either this or defaultvendor. |
| defaultvendor | string(30) | The vendorcode of the referenced vendors, instead of the id. Send this or defaultvendorid, not both unless they agree. |
| shippingnotes | text | Shippingnotes. Stored as text, no practical length limit. |
| contactnameid | integer | Contactnameid. Id only. |
| dropship | boolean | True when the order drop-ships from the vendor directly to the customer. |
| glcategoryid | integer | Glcategoryid. Id only. |
| glcategory | string(20) | The code of the referenced glcategories, instead of the id. Send this or glcategoryid, not both unless they agree. |
| pickticklastprintread-only | string | When the pick ticket was last printed. Maintained by the print flow, so it cannot be written through the API. |
| pickticknumprintread-only | integer | How many times the pick ticket has printed. Maintained by the print flow, so it cannot be written through the API. |
| revisionread-only | integer | Revision counter, incremented each time the order is edited with changes. |
| taxclassid | integer | Taxclassid. Id only. |
| taxclass | string(100) | The name of the referenced taxclasses, instead of the id. Send this or taxclassid, not both unless they agree. |
| unread | boolean | 1 until someone opens the order in NolaPro; new web and B2B orders arrive unread. |
| clonedquotearorderid | integer | Clonedquotearorderid. Id only. |
| ordertotalmoney | string(4dp) | Stored as decimal(19,4). |
| rentalsbillwhen | boolean | For rental orders: when rentals bill (0 = on return, 1 = periodically while out). |
| signaturerequired | boolean | 1 when delivery requires a signature. |
| taxexemptid | integer | Reference to taxexempts, by id. Write either this or taxexempt. |
| taxexempt | string(32) | The exemptname of the referenced taxexempts, instead of the id. Send this or taxexemptid, not both unless they agree. |
| usecontactdetails | boolean | 1 prints the order contact’s details on documents instead of the customer’s main details. |
| billtoshiptoid | integer | Billtoshiptoid. Id only. |
| defaultassetid | integer | Defaultassetid. Id only. |
| effective_statusread-only | integer | Cached derived status used by order lists: -98 = cancelled, -97 = complete, -96 = out on rent, otherwise the order status code. Maintained by the calculation cache, so it cannot be written through the API. |
| passthrucontactid | integer | Passthrucontactid. Id only. |
| passthrucustomerbilltoshiptoid | integer | Passthrucustomerbilltoshiptoid. Id only. |
| passthrucustomerid | integer | Passthrucustomerid. Id only. |
| passthrucustomer | string(30) | The customercode of the referenced customers, instead of the id. Send this or passthrucustomerid, not both unless they agree. |
| ordernumberdisplayread-only | string(30) | STORED GENERATED in the database. Read-only - MySQL computes it, and a value sent here is silently discarded. |
| estimatedmultiplier | integer | Estimated Multiplier applied when estimating the order’s pricing. |
| hidebettervalueinfopdf | integer | 1 hides the better-value pricing block on the printed quote PDF. |
| externalid | string(100) | Your own key. Scoped to your company. |
Endpoints#
Notes on an order and its lines.
As with invoices, but for orders. private marks a note as internal - a support or CRM integration reading these should respect it before showing anything to a customer.
Requires scope orders:read.
| Name | In | Type | Notes |
|---|---|---|---|
| idrequired | path | integer | The order id. |
| Status | Code | Meaning |
|---|---|---|
| 422 | unknown_value | No such parent record in this company. |
curl \ 'https://acme.nolapro.com/!/api/v2/orders/104/notes' \ -H 'Authorization: Bearer $NP_TOKEN'
$ch = curl_init('https://acme.nolapro.com/!/api/v2/orders/104/notes'); curl_setopt_array($ch, [ CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('NP_TOKEN')], CURLOPT_RETURNTRANSFER => true, ]); $res = json_decode(curl_exec($ch), true);
import os, requests r = requests.get( "https://acme.nolapro.com/!/api/v2/orders/104/notes", headers={"Authorization": f"Bearer {os.environ['NP_TOKEN']}"}, ) r.raise_for_status()
const res = await fetch( 'https://acme.nolapro.com/!/api/v2/orders/104/notes', { method: 'GET', headers: { Authorization: `Bearer ${process.env.NP_TOKEN}` }, } ); const data = await res.json();
using System.Net.Http.Json; var token = Environment.GetEnvironmentVariable("NP_TOKEN"); using var http = new HttpClient(); http.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); var res = await http.GetAsync( "https://acme.nolapro.com/!/api/v2/orders/104/notes"); res.EnsureSuccessStatusCode();
Tax charged on an order, by jurisdiction.
The order-level equivalent of the invoice line breakdown. Useful before the order is billed, when the invoice tax detail does not exist yet.
Requires scope orders:read.
| Name | In | Type | Notes |
|---|---|---|---|
| idrequired | path | integer | The order id. |
| Status | Code | Meaning |
|---|---|---|
| 422 | unknown_value | No such parent record in this company. |
curl \ 'https://acme.nolapro.com/!/api/v2/orders/104/tax' \ -H 'Authorization: Bearer $NP_TOKEN'
$ch = curl_init('https://acme.nolapro.com/!/api/v2/orders/104/tax'); curl_setopt_array($ch, [ CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('NP_TOKEN')], CURLOPT_RETURNTRANSFER => true, ]); $res = json_decode(curl_exec($ch), true);
import os, requests r = requests.get( "https://acme.nolapro.com/!/api/v2/orders/104/tax", headers={"Authorization": f"Bearer {os.environ['NP_TOKEN']}"}, ) r.raise_for_status()
const res = await fetch( 'https://acme.nolapro.com/!/api/v2/orders/104/tax', { method: 'GET', headers: { Authorization: `Bearer ${process.env.NP_TOKEN}` }, } ); const data = await res.json();
using System.Net.Http.Json; var token = Environment.GetEnvironmentVariable("NP_TOKEN"); using var http = new HttpClient(); http.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); var res = await http.GetAsync( "https://acme.nolapro.com/!/api/v2/orders/104/tax"); res.EnsureSuccessStatusCode();
Create many.
Requires scope orders:write.
| Name | In | Type | Notes |
|---|---|---|---|
| Field | Type | Description |
|---|---|---|
| customeridrequired | integer | Who is ordering. |
| date | string | Order date. Defaults to today. |
| ponumber | string(30) | The customer's PO number. |
| shiptoid | integer | Ship-to company, if different from the customer. |
| number | string(30) | Order number. Leave it out and NolaPro allocates one. |
| ordertype | string | Order type: fulfillment, service, or rental. One of fulfillment, service, rental. |
| status | string | Send quote to raise a quote, which does NOT commit stock. Anything else confirms the order and reserves inventory. One of quote, unconfirmed, open, partial, billed. |
| externalid | string(100) | Your own identifier for this record. Stored verbatim and returned on reads; GET /<resource>?externalid=... finds it again. |
| linesrequired | array of object | At least one line. The total is derived - do not send it. |
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | The request was malformed. |
| 422 | cannot_invoice_quote | The order is still a quote, so there is nothing billable. |
| 422 | nothing_to_invoice | Nothing shipped and unbilled remains on the document. |
| 422 | rule_violation | NolaPro refused the document. message carries its reason. |
| 422 | unknown_value | A reference did not resolve in this company. |
curl -X POST \ 'https://acme.nolapro.com/!/api/v2/orders/batch' \ -H 'Authorization: Bearer $NP_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: your-unique-key' \ -d '[ { "customerid": 104, "date": "2026-08-02", "ordertype": "fulfillment", "status": "quote", "externalid": "crm-8842", "lines": [ { "quantity": "3.000000", "price": "125.0000" } ] } ]'
$ch = curl_init('https://acme.nolapro.com/!/api/v2/orders/batch'); curl_setopt_array($ch, [ CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('NP_TOKEN')], CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_POSTFIELDS => json_encode([ [ 'customerid' => 104, 'date' => '2026-08-02', 'ordertype' => 'fulfillment', 'status' => 'quote', 'externalid' => 'crm-8842', 'lines' => [ [ 'quantity' => '3.000000', 'price' => '125.0000', ], ], ], ]), ]); $res = json_decode(curl_exec($ch), true);
import os, requests r = requests.post( "https://acme.nolapro.com/!/api/v2/orders/batch", headers={"Authorization": f"Bearer {os.environ['NP_TOKEN']}"}, json=[ { "customerid": 104, "date": "2026-08-02", "ordertype": "fulfillment", "status": "quote", "externalid": "crm-8842", "lines": [ { "quantity": "3.000000", "price": "125.0000", }, ], }, ], ) r.raise_for_status()
const res = await fetch( 'https://acme.nolapro.com/!/api/v2/orders/batch', { method: 'POST', headers: { Authorization: `Bearer ${process.env.NP_TOKEN}` }, body: JSON.stringify([ { customerid: 104, date: "2026-08-02", ordertype: "fulfillment", status: "quote", externalid: "crm-8842", lines: [ { quantity: "3.000000", price: "125.0000", }, ], }, ]), } ); const data = await res.json();
using System.Net.Http.Json; var token = Environment.GetEnvironmentVariable("NP_TOKEN"); using var http = new HttpClient(); http.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); var body = new[] { new { customerid = 104, date = "2026-08-02", ordertype = "fulfillment", status = "quote", externalid = "crm-8842", lines = new[] { new { quantity = "3.000000", price = "125.0000", }, }, }, }; var req = new HttpRequestMessage(HttpMethod.Post, "https://acme.nolapro.com/!/api/v2/orders/batch") { Content = JsonContent.Create(body), }; req.Headers.Add("Idempotency-Key", "your-unique-key"); var res = await http.SendAsync(req); res.EnsureSuccessStatusCode();
{
"results": [
{
"index": 1,
"status": 1
}
]
}
List orders.
Requires scope orders:read.
| Name | In | Type | Notes |
|---|---|---|---|
| ordertype | query | string | Restrict to one ordertype. One of: fulfillment, service, rental. |
| status | query | string | Restrict to one status. One of: quote, unconfirmed, open, partial, billed. |
| orderbycompanyid | query | string | Restrict to one orderbycompanyid. |
| shiptocompanyid | query | string | Restrict to one shiptocompanyid. |
| inventorylocationid | query | string | Restrict to one inventorylocationid. |
| salesmanid | query | string | Restrict to one salesmanid. |
| jobid | query | string | Restrict to one jobid. |
| onum | query | string | onum. Partial match, case-insensitive. |
| ponumber | query | string | ponumber. Partial match, case-insensitive. |
| ordernumber | query | string | Partial match, case insensitive. |
| cancel | query | string | Defaults to false. Pass true or any. |
| modifiedsince | query | string | RFC 3339 UTC timestamp. Returns only records changed since then, including cancelled ones - so cancel defaults to any rather than false when this is used. The response carries _meta.synced_through; store it and send it back next time. |
| externalid | query | string | Exact match on your own key. |
| include | query | string | Comma-separated extras to embed. Only custom_fields is available: the extra fields this install has defined on the record. Off by default, and an unrecognised value is refused rather than ignored. See Conventions. |
| Status | Code | Meaning |
|---|---|---|
| 403 | insufficient_scope | Token lacks read scope. |
curl \ 'https://acme.nolapro.com/!/api/v2/orders' \ -H 'Authorization: Bearer $NP_TOKEN'
$ch = curl_init('https://acme.nolapro.com/!/api/v2/orders'); curl_setopt_array($ch, [ CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('NP_TOKEN')], CURLOPT_RETURNTRANSFER => true, ]); $res = json_decode(curl_exec($ch), true);
import os, requests r = requests.get( "https://acme.nolapro.com/!/api/v2/orders", headers={"Authorization": f"Bearer {os.environ['NP_TOKEN']}"}, ) r.raise_for_status()
const res = await fetch( 'https://acme.nolapro.com/!/api/v2/orders', { method: 'GET', headers: { Authorization: `Bearer ${process.env.NP_TOKEN}` }, } ); const data = await res.json();
using System.Net.Http.Json; var token = Environment.GetEnvironmentVariable("NP_TOKEN"); using var http = new HttpClient(); http.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); var res = await http.GetAsync( "https://acme.nolapro.com/!/api/v2/orders"); res.EnsureSuccessStatusCode();
Create.
Creates an order, a quote or a service order - which one is decided by ordertype and status, not by the URL. Optionally send lines, hours and shipments in the same request: each is attached to the new order inside one transaction. The response echoes the tree in the order you sent it, with real ids, so you can map your input positions.
Requires scope orders:write.
| Name | In | Type | Notes |
|---|---|---|---|
| Field | Type | Description |
|---|---|---|
| customeridrequired | integer | Who is ordering. |
| date | string | Order date. Defaults to today. |
| ponumber | string(30) | The customer's PO number. |
| shiptoid | integer | Ship-to company, if different from the customer. |
| number | string(30) | Order number. Leave it out and NolaPro allocates one. |
| ordertype | string | Order type: fulfillment, service, or rental. One of fulfillment, service, rental. |
| status | string | Send quote to raise a quote, which does NOT commit stock. Anything else confirms the order and reserves inventory. One of quote, unconfirmed, open, partial, billed. |
| externalid | string(100) | Your own identifier for this record. Stored verbatim and returned on reads; GET /<resource>?externalid=... finds it again. |
| linesrequired | array of object | At least one line. The total is derived - do not send it. |
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | A required field was missing. |
| 422 | cannot_invoice_quote | The order is still a quote, so there is nothing billable. |
| 422 | nothing_to_invoice | Nothing shipped and unbilled remains on the document. |
| 422 | rule_violation | NolaPro refused the document. message carries its reason. |
| 422 | unknown_value | A reference did not resolve in this company. |
curl -X POST \ 'https://acme.nolapro.com/!/api/v2/orders' \ -H 'Authorization: Bearer $NP_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: your-unique-key' \ -d '{ "customerid": 104, "date": "2026-08-02", "ordertype": "fulfillment", "status": "quote", "externalid": "crm-8842", "lines": [ { "quantity": "3.000000", "price": "125.0000" } ] }'
$ch = curl_init('https://acme.nolapro.com/!/api/v2/orders'); curl_setopt_array($ch, [ CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('NP_TOKEN')], CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_POSTFIELDS => json_encode([ 'customerid' => 104, 'date' => '2026-08-02', 'ordertype' => 'fulfillment', 'status' => 'quote', 'externalid' => 'crm-8842', 'lines' => [ [ 'quantity' => '3.000000', 'price' => '125.0000', ], ], ]), ]); $res = json_decode(curl_exec($ch), true);
import os, requests r = requests.post( "https://acme.nolapro.com/!/api/v2/orders", headers={"Authorization": f"Bearer {os.environ['NP_TOKEN']}"}, json={ "customerid": 104, "date": "2026-08-02", "ordertype": "fulfillment", "status": "quote", "externalid": "crm-8842", "lines": [ { "quantity": "3.000000", "price": "125.0000", }, ], }, ) r.raise_for_status()
const res = await fetch( 'https://acme.nolapro.com/!/api/v2/orders', { method: 'POST', headers: { Authorization: `Bearer ${process.env.NP_TOKEN}` }, body: JSON.stringify({ customerid: 104, date: "2026-08-02", ordertype: "fulfillment", status: "quote", externalid: "crm-8842", lines: [ { quantity: "3.000000", price: "125.0000", }, ], }), } ); const data = await res.json();
using System.Net.Http.Json; var token = Environment.GetEnvironmentVariable("NP_TOKEN"); using var http = new HttpClient(); http.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); var body = new { customerid = 104, date = "2026-08-02", ordertype = "fulfillment", status = "quote", externalid = "crm-8842", lines = new[] { new { quantity = "3.000000", price = "125.0000", }, }, }; var req = new HttpRequestMessage(HttpMethod.Post, "https://acme.nolapro.com/!/api/v2/orders") { Content = JsonContent.Create(body), }; req.Headers.Add("Idempotency-Key", "your-unique-key"); var res = await http.SendAsync(req); res.EnsureSuccessStatusCode();
{
"ordertype": "fulfillment",
"status": "quote"
}
Retrieve one record.
Requires scope orders:read.
| Name | In | Type | Notes |
|---|---|---|---|
| idrequired | path | integer | The record id. |
| include | query | string | Comma-separated extras to embed. Only custom_fields is available: the extra fields this install has defined on the record. Off by default, and an unrecognised value is refused rather than ignored. See Conventions. |
| Status | Code | Meaning |
|---|---|---|
| 404 | not_found | No record with that id. |
curl \ 'https://acme.nolapro.com/!/api/v2/orders/104' \ -H 'Authorization: Bearer $NP_TOKEN'
$ch = curl_init('https://acme.nolapro.com/!/api/v2/orders/104'); curl_setopt_array($ch, [ CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('NP_TOKEN')], CURLOPT_RETURNTRANSFER => true, ]); $res = json_decode(curl_exec($ch), true);
import os, requests r = requests.get( "https://acme.nolapro.com/!/api/v2/orders/104", headers={"Authorization": f"Bearer {os.environ['NP_TOKEN']}"}, ) r.raise_for_status()
const res = await fetch( 'https://acme.nolapro.com/!/api/v2/orders/104', { method: 'GET', headers: { Authorization: `Bearer ${process.env.NP_TOKEN}` }, } ); const data = await res.json();
using System.Net.Http.Json; var token = Environment.GetEnvironmentVariable("NP_TOKEN"); using var http = new HttpClient(); http.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); var res = await http.GetAsync( "https://acme.nolapro.com/!/api/v2/orders/104"); res.EnsureSuccessStatusCode();
{
"status": "quote",
"ordertype": "fulfillment"
}
Update.
Only the fields you send change. Children cannot be sent here - lines, hours and shipments are create-only (see Conventions). Use the child resource to add, change or remove one. Changing status from quote to open commits inventory for every line and is reported back as an inventory_committed warning.
Requires scope orders:write.
| Name | In | Type | Notes |
|---|---|---|---|
| idrequired | path | integer | The record id. |
| Field | Type | Description |
|---|---|---|
| ponumber | string(30) | The customer's own PO reference. |
| duedate | string | When payment or delivery is expected. |
| externalid | string(100) | Your own identifier for this record. |
| statusid | integer | Service status, by id from GET /orderstatusoptions. Service orders only - no other order type carries the field. 0 clears it. Locked once the order is cancelled or fully billed, exactly as the service order screen locks it. |
| statusoption | string(50) | Service status by NAME instead of id ("Order Complete"). Exact match, trimmed, case-insensitive, against this company's statuses. Send either spelling; both get the same validation. |
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | The request was malformed. |
| 404 | not_found | No such record, or it belongs to another company. |
| 409 | order_already_billed | The order has billed quantities so its header is part of an invoice; or, for the service status, the order is fully billed and the screen locks the status there too. |
| 409 | stale_record | If-Match did not match; someone else changed it first. |
| 422 | rule_violation | NolaPro refused the change. message carries its reason. |
| 422 | unknown_value | statusid or statusoption did not match a service status in this company. |
curl -X PATCH \ 'https://acme.nolapro.com/!/api/v2/orders/104' \ -H 'Authorization: Bearer $NP_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: your-unique-key' \ -d '{ "ponumber": "INV-88421", "duedate": "2026-08-01", "statusid": 104, "statusoption": "Example statusoption" }'
$ch = curl_init('https://acme.nolapro.com/!/api/v2/orders/104'); curl_setopt_array($ch, [ CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('NP_TOKEN')], CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => 'PATCH', CURLOPT_POSTFIELDS => json_encode([ 'ponumber' => 'INV-88421', 'duedate' => '2026-08-01', 'statusid' => 104, 'statusoption' => 'Example statusoption', ]), ]); $res = json_decode(curl_exec($ch), true);
import os, requests r = requests.patch( "https://acme.nolapro.com/!/api/v2/orders/104", headers={"Authorization": f"Bearer {os.environ['NP_TOKEN']}"}, json={ "ponumber": "INV-88421", "duedate": "2026-08-01", "statusid": 104, "statusoption": "Example statusoption", }, ) r.raise_for_status()
const res = await fetch( 'https://acme.nolapro.com/!/api/v2/orders/104', { method: 'PATCH', headers: { Authorization: `Bearer ${process.env.NP_TOKEN}` }, body: JSON.stringify({ ponumber: "INV-88421", duedate: "2026-08-01", statusid: 104, statusoption: "Example statusoption", }), } ); const data = await res.json();
using System.Net.Http.Json; var token = Environment.GetEnvironmentVariable("NP_TOKEN"); using var http = new HttpClient(); http.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); var body = new { ponumber = "INV-88421", duedate = "2026-08-01", statusid = 104, statusoption = "Example statusoption", }; var req = new HttpRequestMessage(HttpMethod.Patch, "https://acme.nolapro.com/!/api/v2/orders/104") { Content = JsonContent.Create(body), }; req.Headers.Add("Idempotency-Key", "your-unique-key"); var res = await http.SendAsync(req); res.EnsureSuccessStatusCode();
Cancel.
Requires scope orders:cancel.
| Name | In | Type | Notes |
|---|---|---|---|
| idrequired | path | integer | The record id. |
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | The request was malformed. |
| 409 | cannot_cancel | Something already depends on this document - a payment, a shipment, an invoice. |
| 422 | unknown_value | No such record in this company. |
curl -X DELETE \ 'https://acme.nolapro.com/!/api/v2/orders/104' \ -H 'Authorization: Bearer $NP_TOKEN'
$ch = curl_init('https://acme.nolapro.com/!/api/v2/orders/104'); curl_setopt_array($ch, [ CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('NP_TOKEN')], CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => 'DELETE', ]); $res = json_decode(curl_exec($ch), true);
import os, requests r = requests.delete( "https://acme.nolapro.com/!/api/v2/orders/104", headers={"Authorization": f"Bearer {os.environ['NP_TOKEN']}"}, ) r.raise_for_status()
const res = await fetch( 'https://acme.nolapro.com/!/api/v2/orders/104', { method: 'DELETE', headers: { Authorization: `Bearer ${process.env.NP_TOKEN}` }, } ); const data = await res.json();
using System.Net.Http.Json; var token = Environment.GetEnvironmentVariable("NP_TOKEN"); using var http = new HttpClient(); http.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); var req = new HttpRequestMessage(HttpMethod.Delete, "https://acme.nolapro.com/!/api/v2/orders/104"); var res = await http.SendAsync(req); res.EnsureSuccessStatusCode();
Invoice this order.
Turns shipped-but-unbilled quantity into invoices. Which engine runs depends on ordertype, and they are not interchangeable:
- service - the hours logged against the order are first converted into lines and a shipment, then invoiced. The order becomes billed.
- fulfillment - invoices whatever has shipped and not yet been billed. Ship first; there is nothing to invoice otherwise.
- rental - invoices rental periods that have come due.
A quote cannot be invoiced. Convert it to an order first.
A deposit alone is invoiceable. arorder2invoice.php:323-324 admits an order when it has shipped-but-unbilled quantity or any arorder_deposit row, so an order with a deposit and nothing shipped still produces an invoice.
Requires scope invoices:write.
| Name | In | Type | Notes |
|---|---|---|---|
| idrequired | path | integer | |
| Field | Type | Description |
|---|---|---|
| invoicedate | string | Invoice date. Defaults to what NolaPro would use. |
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | The request was malformed. |
| 422 | cannot_invoice_quote | The order is still a quote, so there is nothing billable. |
| 422 | nothing_to_invoice | Nothing shipped and unbilled remains on the document. |
| 422 | rule_violation | NolaPro refused the document. message carries its reason. |
| 422 | unknown_value | A reference did not resolve in this company. |
curl -X POST \ 'https://acme.nolapro.com/!/api/v2/orders/104/invoice' \ -H 'Authorization: Bearer $NP_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: your-unique-key' \ -d '{ "invoicedate": "2026-08-02" }'
$ch = curl_init('https://acme.nolapro.com/!/api/v2/orders/104/invoice'); curl_setopt_array($ch, [ CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('NP_TOKEN')], CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_POSTFIELDS => json_encode([ 'invoicedate' => '2026-08-02', ]), ]); $res = json_decode(curl_exec($ch), true);
import os, requests r = requests.post( "https://acme.nolapro.com/!/api/v2/orders/104/invoice", headers={"Authorization": f"Bearer {os.environ['NP_TOKEN']}"}, json={ "invoicedate": "2026-08-02", }, ) r.raise_for_status()
const res = await fetch( 'https://acme.nolapro.com/!/api/v2/orders/104/invoice', { method: 'POST', headers: { Authorization: `Bearer ${process.env.NP_TOKEN}` }, body: JSON.stringify({ invoicedate: "2026-08-02", }), } ); const data = await res.json();
using System.Net.Http.Json; var token = Environment.GetEnvironmentVariable("NP_TOKEN"); using var http = new HttpClient(); http.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); var body = new { invoicedate = "2026-08-02", }; var req = new HttpRequestMessage(HttpMethod.Post, "https://acme.nolapro.com/!/api/v2/orders/104/invoice") { Content = JsonContent.Create(body), }; req.Headers.Add("Idempotency-Key", "your-unique-key"); var res = await http.SendAsync(req); res.EnsureSuccessStatusCode();
{
"orderid": 104,
"notices": "Example notices"
}
Order confirmation as a PDF
The order confirmation exactly as NolaPro prints it, including any Document Center attachments set to combine.
Answers application/pdf, not JSON. Because the body is binary it cannot be carried inside a /batch results array; asking for it there returns 415 not_batchable.
Requires scope orders:read.
| Name | In | Type | Notes |
|---|---|---|---|
| idrequired | path | integer | The record id. |
curl \ 'https://acme.nolapro.com/!/api/v2/orders/104/pdf' \ -H 'Authorization: Bearer $NP_TOKEN'
$ch = curl_init('https://acme.nolapro.com/!/api/v2/orders/104/pdf'); curl_setopt_array($ch, [ CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('NP_TOKEN')], CURLOPT_RETURNTRANSFER => true, ]); $res = json_decode(curl_exec($ch), true);
import os, requests r = requests.get( "https://acme.nolapro.com/!/api/v2/orders/104/pdf", headers={"Authorization": f"Bearer {os.environ['NP_TOKEN']}"}, ) r.raise_for_status()
const res = await fetch( 'https://acme.nolapro.com/!/api/v2/orders/104/pdf', { method: 'GET', headers: { Authorization: `Bearer ${process.env.NP_TOKEN}` }, } ); const data = await res.json();
using System.Net.Http.Json; var token = Environment.GetEnvironmentVariable("NP_TOKEN"); using var http = new HttpClient(); http.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); var res = await http.GetAsync( "https://acme.nolapro.com/!/api/v2/orders/104/pdf"); res.EnsureSuccessStatusCode();
Order as a quote PDF
The same order rendered as a customer-facing quote rather than a confirmation. Prices and terms are laid out for someone deciding, not for someone who has already ordered.
Answers application/pdf, not JSON. Because the body is binary it cannot be carried inside a /batch results array; asking for it there returns 415 not_batchable.
Requires scope orders:read.
| Name | In | Type | Notes |
|---|---|---|---|
| idrequired | path | integer | The record id. |
curl \ 'https://acme.nolapro.com/!/api/v2/orders/104/quote' \ -H 'Authorization: Bearer $NP_TOKEN'
$ch = curl_init('https://acme.nolapro.com/!/api/v2/orders/104/quote'); curl_setopt_array($ch, [ CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('NP_TOKEN')], CURLOPT_RETURNTRANSFER => true, ]); $res = json_decode(curl_exec($ch), true);
import os, requests r = requests.get( "https://acme.nolapro.com/!/api/v2/orders/104/quote", headers={"Authorization": f"Bearer {os.environ['NP_TOKEN']}"}, ) r.raise_for_status()
const res = await fetch( 'https://acme.nolapro.com/!/api/v2/orders/104/quote', { method: 'GET', headers: { Authorization: `Bearer ${process.env.NP_TOKEN}` }, } ); const data = await res.json();
using System.Net.Http.Json; var token = Environment.GetEnvironmentVariable("NP_TOKEN"); using var http = new HttpClient(); http.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); var res = await http.GetAsync( "https://acme.nolapro.com/!/api/v2/orders/104/quote"); res.EnsureSuccessStatusCode();
Pick ticket as a PDF
The warehouse pick list for the order: what to pull and from where. Carries no prices, because it goes to the floor rather than to the customer.
Answers application/pdf, not JSON. Because the body is binary it cannot be carried inside a /batch results array; asking for it there returns 415 not_batchable.
Requires scope orders:read.
| Name | In | Type | Notes |
|---|---|---|---|
| idrequired | path | integer | The record id. |
curl \ 'https://acme.nolapro.com/!/api/v2/orders/104/pickticket' \ -H 'Authorization: Bearer $NP_TOKEN'
$ch = curl_init('https://acme.nolapro.com/!/api/v2/orders/104/pickticket'); curl_setopt_array($ch, [ CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('NP_TOKEN')], CURLOPT_RETURNTRANSFER => true, ]); $res = json_decode(curl_exec($ch), true);
import os, requests r = requests.get( "https://acme.nolapro.com/!/api/v2/orders/104/pickticket", headers={"Authorization": f"Bearer {os.environ['NP_TOKEN']}"}, ) r.raise_for_status()
const res = await fetch( 'https://acme.nolapro.com/!/api/v2/orders/104/pickticket', { method: 'GET', headers: { Authorization: `Bearer ${process.env.NP_TOKEN}` }, } ); const data = await res.json();
using System.Net.Http.Json; var token = Environment.GetEnvironmentVariable("NP_TOKEN"); using var http = new HttpClient(); http.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); var res = await http.GetAsync( "https://acme.nolapro.com/!/api/v2/orders/104/pickticket"); res.EnsureSuccessStatusCode();
Service ticket as a PDF
The service ticket for a service order: the work to be done and the details the technician needs on site.
Answers application/pdf, not JSON. Because the body is binary it cannot be carried inside a /batch results array; asking for it there returns 415 not_batchable.
Requires scope orders:read.
| Name | In | Type | Notes |
|---|---|---|---|
| idrequired | path | integer | The record id. |
curl \ 'https://acme.nolapro.com/!/api/v2/orders/104/serviceticket' \ -H 'Authorization: Bearer $NP_TOKEN'
$ch = curl_init('https://acme.nolapro.com/!/api/v2/orders/104/serviceticket'); curl_setopt_array($ch, [ CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('NP_TOKEN')], CURLOPT_RETURNTRANSFER => true, ]); $res = json_decode(curl_exec($ch), true);
import os, requests r = requests.get( "https://acme.nolapro.com/!/api/v2/orders/104/serviceticket", headers={"Authorization": f"Bearer {os.environ['NP_TOKEN']}"}, ) r.raise_for_status()
const res = await fetch( 'https://acme.nolapro.com/!/api/v2/orders/104/serviceticket', { method: 'GET', headers: { Authorization: `Bearer ${process.env.NP_TOKEN}` }, } ); const data = await res.json();
using System.Net.Http.Json; var token = Environment.GetEnvironmentVariable("NP_TOKEN"); using var http = new HttpClient(); http.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); var res = await http.GetAsync( "https://acme.nolapro.com/!/api/v2/orders/104/serviceticket"); res.EnsureSuccessStatusCode();
Paper/mylar proof request as a PDF
The proof request that goes with the order to the plate room.
Answers application/pdf, not JSON. Because the body is binary it cannot be carried inside a /batch results array; asking for it there returns 415 not_batchable.
Requires scope orders:read.
| Name | In | Type | Notes |
|---|---|---|---|
| idrequired | path | integer | The record id. |
curl \ 'https://acme.nolapro.com/!/api/v2/orders/104/proofrequest' \ -H 'Authorization: Bearer $NP_TOKEN'
$ch = curl_init('https://acme.nolapro.com/!/api/v2/orders/104/proofrequest'); curl_setopt_array($ch, [ CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('NP_TOKEN')], CURLOPT_RETURNTRANSFER => true, ]); $res = json_decode(curl_exec($ch), true);
import os, requests r = requests.get( "https://acme.nolapro.com/!/api/v2/orders/104/proofrequest", headers={"Authorization": f"Bearer {os.environ['NP_TOKEN']}"}, ) r.raise_for_status()
const res = await fetch( 'https://acme.nolapro.com/!/api/v2/orders/104/proofrequest', { method: 'GET', headers: { Authorization: `Bearer ${process.env.NP_TOKEN}` }, } ); const data = await res.json();
using System.Net.Http.Json; var token = Environment.GetEnvironmentVariable("NP_TOKEN"); using var http = new HttpClient(); http.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); var res = await http.GetAsync( "https://acme.nolapro.com/!/api/v2/orders/104/proofrequest"); res.EnsureSuccessStatusCode();
arorderdetail has no cancel column, so DELETE removes the row and renumbers its siblings rather than cancelling it.POST /orders or created on its own afterwards; both go through the same code path. A quote cannot ship.