Customer invoices
Customer invoices: drafts, issuing, e-mail, credit, payments and PDF. An issued invoice never changes.
List customer invoices
GET
/invoices
listInvoices
Customer invoices and credit invoices, drafts included, with rows and payments.
Scope
Parameters
-
limitinteger queryPage size, 1–200.
-
cursorstring queryOpaque cursor from meta.next_cursor of the previous page.
-
updated_sincestring (date-time) queryOnly records whose updated_at is strictly later than this ISO 8601 time. Lists are ordered by updated_at, then id, so a sync stores the updated_at of the last record it has seen and passes it next time, walking all pages with `cursor`.
-
statusstring queryDRAFT, ISSUED (unpaid), PAID or CREDITED.
-
kindstring queryINVOICE or CREDIT.
-
customer_idinteger queryOnly this customer.
-
date_fromstring (date) queryFrom this date (YYYY-MM-DD), inclusive.
-
date_tostring (date) queryUp to this date (YYYY-MM-DD), inclusive.
Responses
200 OK – A page of invoices.
application/jsonobject
-
dataarray<Invoice> required34 fields · each item
-
idstring (uuid) -
numberinteger nullableGapless invoice number, null while a draft.
-
kindstring -
statusstringOpen enum.
-
credits_invoice_idstring (uuid) nullable -
customer_idinteger -
customerobjectThe customer as on the invoice (frozen when issued). Never a personal number.
6 fields
-
numberinteger nullable -
namestring nullable -
org_numberstring nullable -
vat_numberstring nullable -
emailstring nullable -
addressobject5 fields
-
line1string nullable -
line2string nullable -
postal_codestring nullable -
citystring nullable -
countrystring nullable
-
-
-
invoice_datestring (date) -
due_datestring (date) -
delivery_datestring (date) nullable -
your_referencestring nullable -
our_referencestring nullable -
notesstring nullable -
reverse_chargeboolean -
foreign_salestring nullable -
tax_reductionstring nullableROT or RUT.
-
tax_reduction_oreinteger -
property_designationstring nullable -
currencystring -
net_oreinteger -
vat_oreinteger -
rounding_oreintegerÖresavrundning to whole kronor.
-
total_oreinteger -
paid_oreinteger -
remaining_oreinteger -
ocrstring nullable -
voucher_idstring (uuid) nullable -
issued_atstring (date-time) nullable -
sent_atstring (date-time) nullable -
sent_tostring nullable -
rowsarray<InvoiceRow>10 fields · each item
-
articlestring nullable -
descriptionstring -
quantitystringDecimal string, up to three decimals; negative on credit invoices.
-
unitstring -
unit_price_oreinteger -
discount_bpintegerDiscount in basis points (1000 is 10 %).
-
vat_rateinteger -
accountinteger nullable -
net_oreinteger -
labourbooleanLabour cost (ROT/RUT).
-
-
paymentsarray<InvoicePayment>9 fields · each item
-
idinteger -
invoice_idstring (uuid) -
paid_onstring (date) -
amount_oreinteger -
currencystring -
accountinteger nullableBank account the money came in on.
-
voucher_idstring (uuid) -
created_atstring (date-time) -
updated_atstring (date-time)
-
-
created_atstring (date-time) -
updated_atstring (date-time)
-
-
metaListMeta required3 fields
-
limitinteger required -
next_cursorstring required nullableOpaque; pass as `cursor` for the next page. null on the last page.
-
has_moreboolean required
-
401 Unauthorized – Missing, invalid, expired or revoked token or API key. Also returned when the person behind the credential has left the company (an OAuth grant is then revoked for good).
-
unauthenticatedNo valid credentialNyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.
403 Forbidden – The credential may not do this: a scope is missing, the granting person no longer has the permission, the address is not allowed, the company is archived (read-only) or no longer allows the app.
-
insufficient_scopeScope missing or permission lostNyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.
-
forbiddenThe action refuses (for example changing a posted voucher)Behörighet saknas för det här.
-
ip_not_allowedOutside the IP allowlistFöretaget tillåter inte anrop från den här adressen.
-
company_archivedWrite to an archived companyFöretaget är arkiverat och kan bara läsas.
-
app_not_allowedThe company no longer allows the appFöretaget tillåter inte längre den här appen.
404 Not Found – Not found. Also the answer for another company's ids (existence is never revealed) and for every call while NONOX Connect is turned off for the company.
-
not_foundUnknown id, other company's id, or module offDet du söker finns inte.
429 Too Many Requests – Rate limit exceeded (per credential, per company or per address). Wait Retry-After seconds.
-
rate_limitedOver the limitFör många anrop. Försök igen om 23 sekunder.
Code samples
curl "https://nonox.app/api/v1/invoices?limit=50&updated_since=2026-03-01T00%3A00%3A00%2B01%3A00" \
-H "Authorization: Bearer $NONOX_TOKEN" \
-H "Accept: application/json"use Illuminate\Support\Facades\Http;
$response = Http::withToken(config('services.nonox.token'))
->acceptJson()
->get('https://nonox.app/api/v1/invoices', [
'limit' => 50,
'updated_since' => '2026-03-01T00:00:00+01:00',
]);
$response->throw();
$data = $response->json('data');$client = new \GuzzleHttp\Client(['timeout' => 30]);
$response = $client->request('GET', 'https://nonox.app/api/v1/invoices', [
'headers' => [
'Authorization' => 'Bearer '.getenv('NONOX_TOKEN'),
'Accept' => 'application/json',
],
'query' => [
'limit' => 50,
'updated_since' => '2026-03-01T00:00:00+01:00',
],
]);
$data = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR)['data'];const url = new URL('https://nonox.app/api/v1/invoices');
url.searchParams.set('limit', '50');
url.searchParams.set('updated_since', '2026-03-01T00:00:00+01:00');
const response = await fetch(url, {
headers: {
Authorization: `Bearer ${process.env.NONOX_TOKEN}`,
Accept: 'application/json',
},
});
if (!response.ok) {
const problem = await response.json();
throw new Error(`${problem.code}: ${problem.detail}`);
}
const { data } = await response.json();import os
import requests
response = requests.get(
"https://nonox.app/api/v1/invoices",
headers={
"Authorization": f"Bearer {os.environ['NONOX_TOKEN']}",
"Accept": "application/json",
},
params={
"limit": 50,
"updated_since": "2026-03-01T00:00:00+01:00",
},
timeout=30,
)
response.raise_for_status()
data = response.json()["data"]Responses · 200
{
"data": [
{
"id": "5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54",
"number": 1042,
"kind": "INVOICE",
"status": "PAID",
"credits_invoice_id": null,
"customer_id": 18,
"customer": {
"number": 1004,
"name": "Kund Exempel AB",
"org_number": "559900-4560",
"vat_number": "SE559900456001",
"email": "faktura@kund.example.se",
"address": {
"line1": "Kundvägen 5",
"line2": null,
"postal_code": "222 33",
"city": "Exempelby",
"country": "SE"
}
},
"invoice_date": "2026-03-02",
"due_date": "2026-04-01",
"delivery_date": null,
"your_reference": "Anna Exempel",
"our_reference": null,
"notes": null,
"reverse_charge": false,
"foreign_sale": null,
"tax_reduction": null,
"tax_reduction_ore": 0,
"property_designation": null,
"currency": "SEK",
"net_ore": 190000,
"vat_ore": 47500,
"rounding_ore": 0,
"total_ore": 237500,
"paid_ore": 237500,
"remaining_ore": 0,
"ocr": "104257",
"voucher_id": "1d2e3f4a-5b6c-4d7e-8f9a-0b1c2d3e4f5a",
"issued_at": "2026-03-02T10:45:12+01:00",
"sent_at": "2026-03-02T10:45:12+01:00",
"sent_to": "faktura@kund.example.se",
"rows": [
{
"article": "TIM",
"description": "Konsulttimme",
"quantity": "2",
"unit": "h",
"unit_price_ore": 95000,
"discount_bp": 0,
"vat_rate": 2500,
"account": 3001,
"net_ore": 190000,
"labour": false
}
],
"payments": [
{
"id": 88,
"invoice_id": "5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54",
"paid_on": "2026-03-28",
"amount_ore": 237500,
"currency": "SEK",
"account": 1930,
"voucher_id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"created_at": "2026-03-28T09:12:00+01:00",
"updated_at": "2026-03-28T09:12:00+01:00"
}
],
"created_at": "2026-03-02T10:45:12+01:00",
"updated_at": "2026-03-28T09:12:00+01:00"
}
],
"meta": {
"limit": 50,
"next_cursor": null,
"has_more": false
}
}Error
4011 example
{
"type": "urn:nonox:problem:unauthenticated",
"title": "Unauthorized",
"status": 401,
"code": "unauthenticated",
"detail": "Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4035 examples
{
"type": "urn:nonox:problem:insufficient_scope",
"title": "Forbidden",
"status": 403,
"code": "insufficient_scope",
"detail": "Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
"required_scopes": [
"vouchers:post"
]
}{
"type": "urn:nonox:problem:forbidden",
"title": "Forbidden",
"status": 403,
"code": "forbidden",
"detail": "Behörighet saknas för det här.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:ip_not_allowed",
"title": "Forbidden",
"status": 403,
"code": "ip_not_allowed",
"detail": "Företaget tillåter inte anrop från den här adressen.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:company_archived",
"title": "Forbidden",
"status": 403,
"code": "company_archived",
"detail": "Företaget är arkiverat och kan bara läsas.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:app_not_allowed",
"title": "Forbidden",
"status": 403,
"code": "app_not_allowed",
"detail": "Företaget tillåter inte längre den här appen.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4041 example
{
"type": "urn:nonox:problem:not_found",
"title": "Not Found",
"status": 404,
"code": "not_found",
"detail": "Det du söker finns inte.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4291 example
{
"type": "urn:nonox:problem:rate_limited",
"title": "Too Many Requests",
"status": 429,
"code": "rate_limited",
"detail": "För många anrop. Försök igen om 23 sekunder.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}Create a draft invoice
POST
/invoices
createInvoice
Creates a draft. Nothing is booked and no number is taken until it is issued. The due date follows the customer's payment terms unless given; totals, VAT and öresavrundning are calculated. Same Action as the app (SaveDraftInvoice).
Scope
Parameters
-
Idempotency-Keystring header requiredRequired on every POST. A unique value per intended operation (a UUID v4 is ideal), 1–255 visible ASCII characters. Kept 24 hours per credential: the same key with the same request returns the stored response (Idempotent-Replayed: true); with a different request 422 idempotency_key_reused; while the first is still running 409. Server errors (5xx) are not stored, so retry with the same key.
Request body
application/jsonInvoiceInput required
-
customer_idinteger required -
invoice_datestring (date) required -
due_datestring (date) nullable -
delivery_datestring (date) nullable -
your_referencestring nullable -
our_referencestring nullable -
notesstring nullable -
reverse_chargeboolean nullable -
foreign_salestring nullable -
tax_reductionstring nullable -
property_designationstring nullable -
rowsarray<InvoiceRowInput> required9 fields · each item
-
articlestring nullableArticle number. Its name, price and VAT rate are used for fields left out.
-
descriptionstring -
quantityinteger | stringAn integer, or a decimal string such as "1.5". Default 1.
2 fields
-
One of integer
-
One of string
-
-
unitstring -
unit_price_oreinteger -
discount_bpinteger -
vat_rateinteger -
accountinteger nullable -
labourboolean
-
Responses
201 Created – The draft.
application/jsonobject
-
dataInvoice required34 fields
-
idstring (uuid) -
numberinteger nullableGapless invoice number, null while a draft.
-
kindstring -
statusstringOpen enum.
-
credits_invoice_idstring (uuid) nullable -
customer_idinteger -
customerobjectThe customer as on the invoice (frozen when issued). Never a personal number.
6 fields
-
numberinteger nullable -
namestring nullable -
org_numberstring nullable -
vat_numberstring nullable -
emailstring nullable -
addressobject5 fields
-
line1string nullable -
line2string nullable -
postal_codestring nullable -
citystring nullable -
countrystring nullable
-
-
-
invoice_datestring (date) -
due_datestring (date) -
delivery_datestring (date) nullable -
your_referencestring nullable -
our_referencestring nullable -
notesstring nullable -
reverse_chargeboolean -
foreign_salestring nullable -
tax_reductionstring nullableROT or RUT.
-
tax_reduction_oreinteger -
property_designationstring nullable -
currencystring -
net_oreinteger -
vat_oreinteger -
rounding_oreintegerÖresavrundning to whole kronor.
-
total_oreinteger -
paid_oreinteger -
remaining_oreinteger -
ocrstring nullable -
voucher_idstring (uuid) nullable -
issued_atstring (date-time) nullable -
sent_atstring (date-time) nullable -
sent_tostring nullable -
rowsarray<InvoiceRow>10 fields · each item
-
articlestring nullable -
descriptionstring -
quantitystringDecimal string, up to three decimals; negative on credit invoices.
-
unitstring -
unit_price_oreinteger -
discount_bpintegerDiscount in basis points (1000 is 10 %).
-
vat_rateinteger -
accountinteger nullable -
net_oreinteger -
labourbooleanLabour cost (ROT/RUT).
-
-
paymentsarray<InvoicePayment>9 fields · each item
-
idinteger -
invoice_idstring (uuid) -
paid_onstring (date) -
amount_oreinteger -
currencystring -
accountinteger nullableBank account the money came in on.
-
voucher_idstring (uuid) -
created_atstring (date-time) -
updated_atstring (date-time)
-
-
created_atstring (date-time) -
updated_atstring (date-time)
-
400 Bad Request – Bad request: missing or invalid Idempotency-Key, or a body that is not a JSON object.
-
idempotency_key_requiredNo Idempotency-Key on a POSTSkicka en unik Idempotency-Key (till exempel ett UUID) med varje POST, så att ett nytt försök aldrig bokför två gånger.
-
idempotency_key_invalidIdempotency-Key too long or not visible ASCIIIdempotency-Key ska vara 1–255 synliga ASCII-tecken.
-
invalid_jsonMalformed JSONKroppen är inte giltig JSON (ett objekt).
401 Unauthorized – Missing, invalid, expired or revoked token or API key. Also returned when the person behind the credential has left the company (an OAuth grant is then revoked for good).
-
unauthenticatedNo valid credentialNyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.
403 Forbidden – The credential may not do this: a scope is missing, the granting person no longer has the permission, the address is not allowed, the company is archived (read-only) or no longer allows the app.
-
insufficient_scopeScope missing or permission lostNyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.
-
forbiddenThe action refuses (for example changing a posted voucher)Behörighet saknas för det här.
-
ip_not_allowedOutside the IP allowlistFöretaget tillåter inte anrop från den här adressen.
-
company_archivedWrite to an archived companyFöretaget är arkiverat och kan bara läsas.
-
app_not_allowedThe company no longer allows the appFöretaget tillåter inte längre den här appen.
404 Not Found – Not found. Also the answer for another company's ids (existence is never revealed) and for every call while NONOX Connect is turned off for the company.
-
not_foundUnknown id, other company's id, or module offDet du söker finns inte.
409 Conflict – A request with the same Idempotency-Key is still running.
-
idempotency_in_progressSame key, first request not finishedEn begäran med samma Idempotency-Key pågår. Vänta och försök igen.
415 Unsupported Media Type – The body is not application/json (or multipart/form-data where a file is accepted).
-
unsupported_media_typeWrong Content-TypeSkicka JSON (application/json).
422 Unprocessable Content – Validation failed, or the Idempotency-Key was already used for a different request.
-
validation_failedField errorsUppgifterna kunde inte godtas. Se errors.
-
idempotency_key_reusedSame key, different bodyIdempotency-Key har redan använts för en annan begäran. Använd en ny nyckel för en ny begäran.
429 Too Many Requests – Rate limit exceeded (per credential, per company or per address). Wait Retry-After seconds.
-
rate_limitedOver the limitFör många anrop. Försök igen om 23 sekunder.
Code samples
curl -X POST "https://nonox.app/api/v1/invoices" \
-H "Authorization: Bearer $NONOX_TOKEN" \
-H "Accept: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"customer_id": 18,
"invoice_date": "2026-03-02",
"your_reference": "Anna Exempel",
"rows": [
{
"article": "TIM",
"quantity": 2
},
{
"description": "Resa",
"quantity": "1.5",
"unit_price_ore": 20000,
"vat_rate": 2500,
"discount_bp": 1000
}
]
}'use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;
$response = Http::withToken(config('services.nonox.token'))
->acceptJson()
->withHeaders(['Idempotency-Key' => (string) Str::uuid()])
->post('https://nonox.app/api/v1/invoices', [
'customer_id' => 18,
'invoice_date' => '2026-03-02',
'your_reference' => 'Anna Exempel',
'rows' => [
[
'article' => 'TIM',
'quantity' => 2,
],
[
'description' => 'Resa',
'quantity' => '1.5',
'unit_price_ore' => 20000,
'vat_rate' => 2500,
'discount_bp' => 1000,
],
],
]);
$response->throw();
$data = $response->json('data');$client = new \GuzzleHttp\Client(['timeout' => 30]);
$response = $client->request('POST', 'https://nonox.app/api/v1/invoices', [
'headers' => [
'Authorization' => 'Bearer '.getenv('NONOX_TOKEN'),
'Accept' => 'application/json',
'Idempotency-Key' => bin2hex(random_bytes(16)),
],
'json' => [
'customer_id' => 18,
'invoice_date' => '2026-03-02',
'your_reference' => 'Anna Exempel',
'rows' => [
[
'article' => 'TIM',
'quantity' => 2,
],
[
'description' => 'Resa',
'quantity' => '1.5',
'unit_price_ore' => 20000,
'vat_rate' => 2500,
'discount_bp' => 1000,
],
],
],
]);
$data = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR)['data'];const response = await fetch('https://nonox.app/api/v1/invoices', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.NONOX_TOKEN}`,
Accept: 'application/json',
'Idempotency-Key': crypto.randomUUID(),
'Content-Type': 'application/json',
},
body: JSON.stringify({
"customer_id": 18,
"invoice_date": "2026-03-02",
"your_reference": "Anna Exempel",
"rows": [
{
"article": "TIM",
"quantity": 2
},
{
"description": "Resa",
"quantity": "1.5",
"unit_price_ore": 20000,
"vat_rate": 2500,
"discount_bp": 1000
}
]
}),
});
if (!response.ok) {
const problem = await response.json();
throw new Error(`${problem.code}: ${problem.detail}`);
}
const { data } = await response.json();import os
import uuid
import requests
response = requests.post(
"https://nonox.app/api/v1/invoices",
headers={
"Authorization": f"Bearer {os.environ['NONOX_TOKEN']}",
"Accept": "application/json",
"Idempotency-Key": str(uuid.uuid4()),
},
json={
"customer_id": 18,
"invoice_date": "2026-03-02",
"your_reference": "Anna Exempel",
"rows": [
{
"article": "TIM",
"quantity": 2,
},
{
"description": "Resa",
"quantity": "1.5",
"unit_price_ore": 20000,
"vat_rate": 2500,
"discount_bp": 1000,
},
],
},
timeout=30,
)
response.raise_for_status()
data = response.json()["data"]Responses · 201
{
"data": {
"id": "5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54",
"number": 1042,
"kind": "INVOICE",
"status": "PAID",
"credits_invoice_id": null,
"customer_id": 18,
"customer": {
"number": 1004,
"name": "Kund Exempel AB",
"org_number": "559900-4560",
"vat_number": "SE559900456001",
"email": "faktura@kund.example.se",
"address": {
"line1": "Kundvägen 5",
"line2": null,
"postal_code": "222 33",
"city": "Exempelby",
"country": "SE"
}
},
"invoice_date": "2026-03-02",
"due_date": "2026-04-01",
"delivery_date": null,
"your_reference": "Anna Exempel",
"our_reference": null,
"notes": null,
"reverse_charge": false,
"foreign_sale": null,
"tax_reduction": null,
"tax_reduction_ore": 0,
"property_designation": null,
"currency": "SEK",
"net_ore": 190000,
"vat_ore": 47500,
"rounding_ore": 0,
"total_ore": 237500,
"paid_ore": 237500,
"remaining_ore": 0,
"ocr": "104257",
"voucher_id": "1d2e3f4a-5b6c-4d7e-8f9a-0b1c2d3e4f5a",
"issued_at": "2026-03-02T10:45:12+01:00",
"sent_at": "2026-03-02T10:45:12+01:00",
"sent_to": "faktura@kund.example.se",
"rows": [
{
"article": "TIM",
"description": "Konsulttimme",
"quantity": "2",
"unit": "h",
"unit_price_ore": 95000,
"discount_bp": 0,
"vat_rate": 2500,
"account": 3001,
"net_ore": 190000,
"labour": false
}
],
"payments": [
{
"id": 88,
"invoice_id": "5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54",
"paid_on": "2026-03-28",
"amount_ore": 237500,
"currency": "SEK",
"account": 1930,
"voucher_id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"created_at": "2026-03-28T09:12:00+01:00",
"updated_at": "2026-03-28T09:12:00+01:00"
}
],
"created_at": "2026-03-02T10:45:12+01:00",
"updated_at": "2026-03-28T09:12:00+01:00"
}
}Error
4003 examples
{
"type": "urn:nonox:problem:idempotency_key_required",
"title": "Bad Request",
"status": 400,
"code": "idempotency_key_required",
"detail": "Skicka en unik Idempotency-Key (till exempel ett UUID) med varje POST, så att ett nytt försök aldrig bokför två gånger.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:idempotency_key_invalid",
"title": "Bad Request",
"status": 400,
"code": "idempotency_key_invalid",
"detail": "Idempotency-Key ska vara 1–255 synliga ASCII-tecken.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:invalid_json",
"title": "Bad Request",
"status": 400,
"code": "invalid_json",
"detail": "Kroppen är inte giltig JSON (ett objekt).",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4011 example
{
"type": "urn:nonox:problem:unauthenticated",
"title": "Unauthorized",
"status": 401,
"code": "unauthenticated",
"detail": "Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4035 examples
{
"type": "urn:nonox:problem:insufficient_scope",
"title": "Forbidden",
"status": 403,
"code": "insufficient_scope",
"detail": "Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
"required_scopes": [
"vouchers:post"
]
}{
"type": "urn:nonox:problem:forbidden",
"title": "Forbidden",
"status": 403,
"code": "forbidden",
"detail": "Behörighet saknas för det här.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:ip_not_allowed",
"title": "Forbidden",
"status": 403,
"code": "ip_not_allowed",
"detail": "Företaget tillåter inte anrop från den här adressen.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:company_archived",
"title": "Forbidden",
"status": 403,
"code": "company_archived",
"detail": "Företaget är arkiverat och kan bara läsas.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:app_not_allowed",
"title": "Forbidden",
"status": 403,
"code": "app_not_allowed",
"detail": "Företaget tillåter inte längre den här appen.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4041 example
{
"type": "urn:nonox:problem:not_found",
"title": "Not Found",
"status": 404,
"code": "not_found",
"detail": "Det du söker finns inte.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4091 example
{
"type": "urn:nonox:problem:idempotency_in_progress",
"title": "Conflict",
"status": 409,
"code": "idempotency_in_progress",
"detail": "En begäran med samma Idempotency-Key pågår. Vänta och försök igen.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4151 example
{
"type": "urn:nonox:problem:unsupported_media_type",
"title": "Unsupported Media Type",
"status": 415,
"code": "unsupported_media_type",
"detail": "Skicka JSON (application/json).",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4222 examples
{
"type": "urn:nonox:problem:validation_failed",
"title": "Unprocessable Content",
"status": 422,
"code": "validation_failed",
"detail": "Uppgifterna kunde inte godtas. Se errors.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
"errors": {
"rows": [
"Verifikationen balanserar inte: debet och kredit skiljer sig åt."
],
"voucher_date": [
"Det finns inget räkenskapsår som omfattar 2031-01-01."
]
}
}{
"type": "urn:nonox:problem:idempotency_key_reused",
"title": "Unprocessable Content",
"status": 422,
"code": "idempotency_key_reused",
"detail": "Idempotency-Key har redan använts för en annan begäran. Använd en ny nyckel för en ny begäran.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4291 example
{
"type": "urn:nonox:problem:rate_limited",
"title": "Too Many Requests",
"status": 429,
"code": "rate_limited",
"detail": "För många anrop. Försök igen om 23 sekunder.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}Get a customer invoice
GET
/invoices/{invoice}
getInvoice
One invoice with rows and payments. Never a personal number.
Scope
Parameters
-
invoicestring (uuid) path requiredInvoice id (UUID, not the invoice number).
Responses
200 OK – The invoice.
application/jsonobject
-
dataInvoice required34 fields
-
idstring (uuid) -
numberinteger nullableGapless invoice number, null while a draft.
-
kindstring -
statusstringOpen enum.
-
credits_invoice_idstring (uuid) nullable -
customer_idinteger -
customerobjectThe customer as on the invoice (frozen when issued). Never a personal number.
6 fields
-
numberinteger nullable -
namestring nullable -
org_numberstring nullable -
vat_numberstring nullable -
emailstring nullable -
addressobject5 fields
-
line1string nullable -
line2string nullable -
postal_codestring nullable -
citystring nullable -
countrystring nullable
-
-
-
invoice_datestring (date) -
due_datestring (date) -
delivery_datestring (date) nullable -
your_referencestring nullable -
our_referencestring nullable -
notesstring nullable -
reverse_chargeboolean -
foreign_salestring nullable -
tax_reductionstring nullableROT or RUT.
-
tax_reduction_oreinteger -
property_designationstring nullable -
currencystring -
net_oreinteger -
vat_oreinteger -
rounding_oreintegerÖresavrundning to whole kronor.
-
total_oreinteger -
paid_oreinteger -
remaining_oreinteger -
ocrstring nullable -
voucher_idstring (uuid) nullable -
issued_atstring (date-time) nullable -
sent_atstring (date-time) nullable -
sent_tostring nullable -
rowsarray<InvoiceRow>10 fields · each item
-
articlestring nullable -
descriptionstring -
quantitystringDecimal string, up to three decimals; negative on credit invoices.
-
unitstring -
unit_price_oreinteger -
discount_bpintegerDiscount in basis points (1000 is 10 %).
-
vat_rateinteger -
accountinteger nullable -
net_oreinteger -
labourbooleanLabour cost (ROT/RUT).
-
-
paymentsarray<InvoicePayment>9 fields · each item
-
idinteger -
invoice_idstring (uuid) -
paid_onstring (date) -
amount_oreinteger -
currencystring -
accountinteger nullableBank account the money came in on.
-
voucher_idstring (uuid) -
created_atstring (date-time) -
updated_atstring (date-time)
-
-
created_atstring (date-time) -
updated_atstring (date-time)
-
401 Unauthorized – Missing, invalid, expired or revoked token or API key. Also returned when the person behind the credential has left the company (an OAuth grant is then revoked for good).
-
unauthenticatedNo valid credentialNyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.
403 Forbidden – The credential may not do this: a scope is missing, the granting person no longer has the permission, the address is not allowed, the company is archived (read-only) or no longer allows the app.
-
insufficient_scopeScope missing or permission lostNyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.
-
forbiddenThe action refuses (for example changing a posted voucher)Behörighet saknas för det här.
-
ip_not_allowedOutside the IP allowlistFöretaget tillåter inte anrop från den här adressen.
-
company_archivedWrite to an archived companyFöretaget är arkiverat och kan bara läsas.
-
app_not_allowedThe company no longer allows the appFöretaget tillåter inte längre den här appen.
404 Not Found – Not found. Also the answer for another company's ids (existence is never revealed) and for every call while NONOX Connect is turned off for the company.
-
not_foundUnknown id, other company's id, or module offDet du söker finns inte.
429 Too Many Requests – Rate limit exceeded (per credential, per company or per address). Wait Retry-After seconds.
-
rate_limitedOver the limitFör många anrop. Försök igen om 23 sekunder.
Code samples
curl "https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54" \
-H "Authorization: Bearer $NONOX_TOKEN" \
-H "Accept: application/json"use Illuminate\Support\Facades\Http;
$response = Http::withToken(config('services.nonox.token'))
->acceptJson()
->get('https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54');
$response->throw();
$data = $response->json('data');$client = new \GuzzleHttp\Client(['timeout' => 30]);
$response = $client->request('GET', 'https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54', [
'headers' => [
'Authorization' => 'Bearer '.getenv('NONOX_TOKEN'),
'Accept' => 'application/json',
],
]);
$data = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR)['data'];const response = await fetch('https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54', {
headers: {
Authorization: `Bearer ${process.env.NONOX_TOKEN}`,
Accept: 'application/json',
},
});
if (!response.ok) {
const problem = await response.json();
throw new Error(`${problem.code}: ${problem.detail}`);
}
const { data } = await response.json();import os
import requests
response = requests.get(
"https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54",
headers={
"Authorization": f"Bearer {os.environ['NONOX_TOKEN']}",
"Accept": "application/json",
},
timeout=30,
)
response.raise_for_status()
data = response.json()["data"]Responses · 200
{
"data": {
"id": "5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54",
"number": 1042,
"kind": "INVOICE",
"status": "PAID",
"credits_invoice_id": null,
"customer_id": 18,
"customer": {
"number": 1004,
"name": "Kund Exempel AB",
"org_number": "559900-4560",
"vat_number": "SE559900456001",
"email": "faktura@kund.example.se",
"address": {
"line1": "Kundvägen 5",
"line2": null,
"postal_code": "222 33",
"city": "Exempelby",
"country": "SE"
}
},
"invoice_date": "2026-03-02",
"due_date": "2026-04-01",
"delivery_date": null,
"your_reference": "Anna Exempel",
"our_reference": null,
"notes": null,
"reverse_charge": false,
"foreign_sale": null,
"tax_reduction": null,
"tax_reduction_ore": 0,
"property_designation": null,
"currency": "SEK",
"net_ore": 190000,
"vat_ore": 47500,
"rounding_ore": 0,
"total_ore": 237500,
"paid_ore": 237500,
"remaining_ore": 0,
"ocr": "104257",
"voucher_id": "1d2e3f4a-5b6c-4d7e-8f9a-0b1c2d3e4f5a",
"issued_at": "2026-03-02T10:45:12+01:00",
"sent_at": "2026-03-02T10:45:12+01:00",
"sent_to": "faktura@kund.example.se",
"rows": [
{
"article": "TIM",
"description": "Konsulttimme",
"quantity": "2",
"unit": "h",
"unit_price_ore": 95000,
"discount_bp": 0,
"vat_rate": 2500,
"account": 3001,
"net_ore": 190000,
"labour": false
}
],
"payments": [
{
"id": 88,
"invoice_id": "5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54",
"paid_on": "2026-03-28",
"amount_ore": 237500,
"currency": "SEK",
"account": 1930,
"voucher_id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"created_at": "2026-03-28T09:12:00+01:00",
"updated_at": "2026-03-28T09:12:00+01:00"
}
],
"created_at": "2026-03-02T10:45:12+01:00",
"updated_at": "2026-03-28T09:12:00+01:00"
}
}Error
4011 example
{
"type": "urn:nonox:problem:unauthenticated",
"title": "Unauthorized",
"status": 401,
"code": "unauthenticated",
"detail": "Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4035 examples
{
"type": "urn:nonox:problem:insufficient_scope",
"title": "Forbidden",
"status": 403,
"code": "insufficient_scope",
"detail": "Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
"required_scopes": [
"vouchers:post"
]
}{
"type": "urn:nonox:problem:forbidden",
"title": "Forbidden",
"status": 403,
"code": "forbidden",
"detail": "Behörighet saknas för det här.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:ip_not_allowed",
"title": "Forbidden",
"status": 403,
"code": "ip_not_allowed",
"detail": "Företaget tillåter inte anrop från den här adressen.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:company_archived",
"title": "Forbidden",
"status": 403,
"code": "company_archived",
"detail": "Företaget är arkiverat och kan bara läsas.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:app_not_allowed",
"title": "Forbidden",
"status": 403,
"code": "app_not_allowed",
"detail": "Företaget tillåter inte längre den här appen.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4041 example
{
"type": "urn:nonox:problem:not_found",
"title": "Not Found",
"status": 404,
"code": "not_found",
"detail": "Det du söker finns inte.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4291 example
{
"type": "urn:nonox:problem:rate_limited",
"title": "Too Many Requests",
"status": 429,
"code": "rate_limited",
"detail": "För många anrop. Försök igen om 23 sekunder.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}Change a draft invoice
PATCH
/invoices/{invoice}
updateInvoice
Changes a draft; an issued invoice answers 403 and never changes.
Scope
Parameters
-
invoicestring (uuid) path requiredInvoice id (UUID, not the invoice number).
Request body
application/jsonInvoicePatch required
Only the fields sent are changed; `rows`, when sent, replaces all rows.
-
customer_idinteger -
invoice_datestring (date) -
due_datestring (date) nullable -
delivery_datestring (date) nullable -
your_referencestring nullable -
our_referencestring nullable -
notesstring nullable -
reverse_chargeboolean nullable -
foreign_salestring nullable -
tax_reductionstring nullable -
property_designationstring nullable -
rowsarray<InvoiceRowInput>9 fields · each item
-
articlestring nullableArticle number. Its name, price and VAT rate are used for fields left out.
-
descriptionstring -
quantityinteger | stringAn integer, or a decimal string such as "1.5". Default 1.
2 fields
-
One of integer
-
One of string
-
-
unitstring -
unit_price_oreinteger -
discount_bpinteger -
vat_rateinteger -
accountinteger nullable -
labourboolean
-
Responses
200 OK – The draft.
application/jsonobject
-
dataInvoice required34 fields
-
idstring (uuid) -
numberinteger nullableGapless invoice number, null while a draft.
-
kindstring -
statusstringOpen enum.
-
credits_invoice_idstring (uuid) nullable -
customer_idinteger -
customerobjectThe customer as on the invoice (frozen when issued). Never a personal number.
6 fields
-
numberinteger nullable -
namestring nullable -
org_numberstring nullable -
vat_numberstring nullable -
emailstring nullable -
addressobject5 fields
-
line1string nullable -
line2string nullable -
postal_codestring nullable -
citystring nullable -
countrystring nullable
-
-
-
invoice_datestring (date) -
due_datestring (date) -
delivery_datestring (date) nullable -
your_referencestring nullable -
our_referencestring nullable -
notesstring nullable -
reverse_chargeboolean -
foreign_salestring nullable -
tax_reductionstring nullableROT or RUT.
-
tax_reduction_oreinteger -
property_designationstring nullable -
currencystring -
net_oreinteger -
vat_oreinteger -
rounding_oreintegerÖresavrundning to whole kronor.
-
total_oreinteger -
paid_oreinteger -
remaining_oreinteger -
ocrstring nullable -
voucher_idstring (uuid) nullable -
issued_atstring (date-time) nullable -
sent_atstring (date-time) nullable -
sent_tostring nullable -
rowsarray<InvoiceRow>10 fields · each item
-
articlestring nullable -
descriptionstring -
quantitystringDecimal string, up to three decimals; negative on credit invoices.
-
unitstring -
unit_price_oreinteger -
discount_bpintegerDiscount in basis points (1000 is 10 %).
-
vat_rateinteger -
accountinteger nullable -
net_oreinteger -
labourbooleanLabour cost (ROT/RUT).
-
-
paymentsarray<InvoicePayment>9 fields · each item
-
idinteger -
invoice_idstring (uuid) -
paid_onstring (date) -
amount_oreinteger -
currencystring -
accountinteger nullableBank account the money came in on.
-
voucher_idstring (uuid) -
created_atstring (date-time) -
updated_atstring (date-time)
-
-
created_atstring (date-time) -
updated_atstring (date-time)
-
401 Unauthorized – Missing, invalid, expired or revoked token or API key. Also returned when the person behind the credential has left the company (an OAuth grant is then revoked for good).
-
unauthenticatedNo valid credentialNyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.
403 Forbidden – The credential may not do this: a scope is missing, the granting person no longer has the permission, the address is not allowed, the company is archived (read-only) or no longer allows the app.
-
insufficient_scopeScope missing or permission lostNyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.
-
forbiddenThe action refuses (for example changing a posted voucher)Behörighet saknas för det här.
-
ip_not_allowedOutside the IP allowlistFöretaget tillåter inte anrop från den här adressen.
-
company_archivedWrite to an archived companyFöretaget är arkiverat och kan bara läsas.
-
app_not_allowedThe company no longer allows the appFöretaget tillåter inte längre den här appen.
404 Not Found – Not found. Also the answer for another company's ids (existence is never revealed) and for every call while NONOX Connect is turned off for the company.
-
not_foundUnknown id, other company's id, or module offDet du söker finns inte.
415 Unsupported Media Type – The body is not application/json (or multipart/form-data where a file is accepted).
-
unsupported_media_typeWrong Content-TypeSkicka JSON (application/json).
422 Unprocessable Content – Validation failed, or the Idempotency-Key was already used for a different request.
-
validation_failedField errorsUppgifterna kunde inte godtas. Se errors.
-
idempotency_key_reusedSame key, different bodyIdempotency-Key har redan använts för en annan begäran. Använd en ny nyckel för en ny begäran.
429 Too Many Requests – Rate limit exceeded (per credential, per company or per address). Wait Retry-After seconds.
-
rate_limitedOver the limitFör många anrop. Försök igen om 23 sekunder.
Code samples
curl -X PATCH "https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54" \
-H "Authorization: Bearer $NONOX_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"your_reference": "Anna Exempel"
}'use Illuminate\Support\Facades\Http;
$response = Http::withToken(config('services.nonox.token'))
->acceptJson()
->patch('https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54', [
'your_reference' => 'Anna Exempel',
]);
$response->throw();
$data = $response->json('data');$client = new \GuzzleHttp\Client(['timeout' => 30]);
$response = $client->request('PATCH', 'https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54', [
'headers' => [
'Authorization' => 'Bearer '.getenv('NONOX_TOKEN'),
'Accept' => 'application/json',
],
'json' => [
'your_reference' => 'Anna Exempel',
],
]);
$data = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR)['data'];const response = await fetch('https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54', {
method: 'PATCH',
headers: {
Authorization: `Bearer ${process.env.NONOX_TOKEN}`,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"your_reference": "Anna Exempel"
}),
});
if (!response.ok) {
const problem = await response.json();
throw new Error(`${problem.code}: ${problem.detail}`);
}
const { data } = await response.json();import os
import requests
response = requests.patch(
"https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54",
headers={
"Authorization": f"Bearer {os.environ['NONOX_TOKEN']}",
"Accept": "application/json",
},
json={
"your_reference": "Anna Exempel",
},
timeout=30,
)
response.raise_for_status()
data = response.json()["data"]Responses · 200
{
"data": {
"id": "5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54",
"number": 1042,
"kind": "INVOICE",
"status": "PAID",
"credits_invoice_id": null,
"customer_id": 18,
"customer": {
"number": 1004,
"name": "Kund Exempel AB",
"org_number": "559900-4560",
"vat_number": "SE559900456001",
"email": "faktura@kund.example.se",
"address": {
"line1": "Kundvägen 5",
"line2": null,
"postal_code": "222 33",
"city": "Exempelby",
"country": "SE"
}
},
"invoice_date": "2026-03-02",
"due_date": "2026-04-01",
"delivery_date": null,
"your_reference": "Anna Exempel",
"our_reference": null,
"notes": null,
"reverse_charge": false,
"foreign_sale": null,
"tax_reduction": null,
"tax_reduction_ore": 0,
"property_designation": null,
"currency": "SEK",
"net_ore": 190000,
"vat_ore": 47500,
"rounding_ore": 0,
"total_ore": 237500,
"paid_ore": 237500,
"remaining_ore": 0,
"ocr": "104257",
"voucher_id": "1d2e3f4a-5b6c-4d7e-8f9a-0b1c2d3e4f5a",
"issued_at": "2026-03-02T10:45:12+01:00",
"sent_at": "2026-03-02T10:45:12+01:00",
"sent_to": "faktura@kund.example.se",
"rows": [
{
"article": "TIM",
"description": "Konsulttimme",
"quantity": "2",
"unit": "h",
"unit_price_ore": 95000,
"discount_bp": 0,
"vat_rate": 2500,
"account": 3001,
"net_ore": 190000,
"labour": false
}
],
"payments": [
{
"id": 88,
"invoice_id": "5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54",
"paid_on": "2026-03-28",
"amount_ore": 237500,
"currency": "SEK",
"account": 1930,
"voucher_id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"created_at": "2026-03-28T09:12:00+01:00",
"updated_at": "2026-03-28T09:12:00+01:00"
}
],
"created_at": "2026-03-02T10:45:12+01:00",
"updated_at": "2026-03-28T09:12:00+01:00"
}
}Error
4011 example
{
"type": "urn:nonox:problem:unauthenticated",
"title": "Unauthorized",
"status": 401,
"code": "unauthenticated",
"detail": "Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4035 examples
{
"type": "urn:nonox:problem:insufficient_scope",
"title": "Forbidden",
"status": 403,
"code": "insufficient_scope",
"detail": "Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
"required_scopes": [
"vouchers:post"
]
}{
"type": "urn:nonox:problem:forbidden",
"title": "Forbidden",
"status": 403,
"code": "forbidden",
"detail": "Behörighet saknas för det här.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:ip_not_allowed",
"title": "Forbidden",
"status": 403,
"code": "ip_not_allowed",
"detail": "Företaget tillåter inte anrop från den här adressen.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:company_archived",
"title": "Forbidden",
"status": 403,
"code": "company_archived",
"detail": "Företaget är arkiverat och kan bara läsas.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:app_not_allowed",
"title": "Forbidden",
"status": 403,
"code": "app_not_allowed",
"detail": "Företaget tillåter inte längre den här appen.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4041 example
{
"type": "urn:nonox:problem:not_found",
"title": "Not Found",
"status": 404,
"code": "not_found",
"detail": "Det du söker finns inte.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4151 example
{
"type": "urn:nonox:problem:unsupported_media_type",
"title": "Unsupported Media Type",
"status": 415,
"code": "unsupported_media_type",
"detail": "Skicka JSON (application/json).",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4222 examples
{
"type": "urn:nonox:problem:validation_failed",
"title": "Unprocessable Content",
"status": 422,
"code": "validation_failed",
"detail": "Uppgifterna kunde inte godtas. Se errors.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
"errors": {
"rows": [
"Verifikationen balanserar inte: debet och kredit skiljer sig åt."
],
"voucher_date": [
"Det finns inget räkenskapsår som omfattar 2031-01-01."
]
}
}{
"type": "urn:nonox:problem:idempotency_key_reused",
"title": "Unprocessable Content",
"status": 422,
"code": "idempotency_key_reused",
"detail": "Idempotency-Key har redan använts för en annan begäran. Använd en ny nyckel för en ny begäran.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4291 example
{
"type": "urn:nonox:problem:rate_limited",
"title": "Too Many Requests",
"status": 429,
"code": "rate_limited",
"detail": "För många anrop. Försök igen om 23 sekunder.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}Issue (book) a draft invoice
POST
/invoices/{invoice}/issue
issueInvoice
Makes the draft an invoice: the next gapless invoice number, an OCR reference, the customer frozen, and under fakturametoden a voucher in series B. Irreversible; a mistake is credited. Does not e-mail it (see /send). Books a voucher as the person behind the credential, so the credential also needs vouchers:create and vouchers:post. Same Action as the app (IssueInvoice).
Scope
invoices:send + vouchers:create + vouchers:post
Parameters
-
invoicestring (uuid) path requiredInvoice id (UUID, not the invoice number).
-
Idempotency-Keystring header requiredRequired on every POST. A unique value per intended operation (a UUID v4 is ideal), 1–255 visible ASCII characters. Kept 24 hours per credential: the same key with the same request returns the stored response (Idempotent-Replayed: true); with a different request 422 idempotency_key_reused; while the first is still running 409. Server errors (5xx) are not stored, so retry with the same key.
Responses
200 OK – The issued invoice.
application/jsonobject
-
dataInvoice required34 fields
-
idstring (uuid) -
numberinteger nullableGapless invoice number, null while a draft.
-
kindstring -
statusstringOpen enum.
-
credits_invoice_idstring (uuid) nullable -
customer_idinteger -
customerobjectThe customer as on the invoice (frozen when issued). Never a personal number.
6 fields
-
numberinteger nullable -
namestring nullable -
org_numberstring nullable -
vat_numberstring nullable -
emailstring nullable -
addressobject5 fields
-
line1string nullable -
line2string nullable -
postal_codestring nullable -
citystring nullable -
countrystring nullable
-
-
-
invoice_datestring (date) -
due_datestring (date) -
delivery_datestring (date) nullable -
your_referencestring nullable -
our_referencestring nullable -
notesstring nullable -
reverse_chargeboolean -
foreign_salestring nullable -
tax_reductionstring nullableROT or RUT.
-
tax_reduction_oreinteger -
property_designationstring nullable -
currencystring -
net_oreinteger -
vat_oreinteger -
rounding_oreintegerÖresavrundning to whole kronor.
-
total_oreinteger -
paid_oreinteger -
remaining_oreinteger -
ocrstring nullable -
voucher_idstring (uuid) nullable -
issued_atstring (date-time) nullable -
sent_atstring (date-time) nullable -
sent_tostring nullable -
rowsarray<InvoiceRow>10 fields · each item
-
articlestring nullable -
descriptionstring -
quantitystringDecimal string, up to three decimals; negative on credit invoices.
-
unitstring -
unit_price_oreinteger -
discount_bpintegerDiscount in basis points (1000 is 10 %).
-
vat_rateinteger -
accountinteger nullable -
net_oreinteger -
labourbooleanLabour cost (ROT/RUT).
-
-
paymentsarray<InvoicePayment>9 fields · each item
-
idinteger -
invoice_idstring (uuid) -
paid_onstring (date) -
amount_oreinteger -
currencystring -
accountinteger nullableBank account the money came in on.
-
voucher_idstring (uuid) -
created_atstring (date-time) -
updated_atstring (date-time)
-
-
created_atstring (date-time) -
updated_atstring (date-time)
-
400 Bad Request – Bad request: missing or invalid Idempotency-Key, or a body that is not a JSON object.
-
idempotency_key_requiredNo Idempotency-Key on a POSTSkicka en unik Idempotency-Key (till exempel ett UUID) med varje POST, så att ett nytt försök aldrig bokför två gånger.
-
idempotency_key_invalidIdempotency-Key too long or not visible ASCIIIdempotency-Key ska vara 1–255 synliga ASCII-tecken.
-
invalid_jsonMalformed JSONKroppen är inte giltig JSON (ett objekt).
401 Unauthorized – Missing, invalid, expired or revoked token or API key. Also returned when the person behind the credential has left the company (an OAuth grant is then revoked for good).
-
unauthenticatedNo valid credentialNyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.
403 Forbidden – The credential may not do this: a scope is missing, the granting person no longer has the permission, the address is not allowed, the company is archived (read-only) or no longer allows the app.
-
insufficient_scopeScope missing or permission lostNyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.
-
forbiddenThe action refuses (for example changing a posted voucher)Behörighet saknas för det här.
-
ip_not_allowedOutside the IP allowlistFöretaget tillåter inte anrop från den här adressen.
-
company_archivedWrite to an archived companyFöretaget är arkiverat och kan bara läsas.
-
app_not_allowedThe company no longer allows the appFöretaget tillåter inte längre den här appen.
404 Not Found – Not found. Also the answer for another company's ids (existence is never revealed) and for every call while NONOX Connect is turned off for the company.
-
not_foundUnknown id, other company's id, or module offDet du söker finns inte.
409 Conflict – A request with the same Idempotency-Key is still running.
-
idempotency_in_progressSame key, first request not finishedEn begäran med samma Idempotency-Key pågår. Vänta och försök igen.
415 Unsupported Media Type – The body is not application/json (or multipart/form-data where a file is accepted).
-
unsupported_media_typeWrong Content-TypeSkicka JSON (application/json).
422 Unprocessable Content – Validation failed, or the Idempotency-Key was already used for a different request.
-
validation_failedField errorsUppgifterna kunde inte godtas. Se errors.
-
idempotency_key_reusedSame key, different bodyIdempotency-Key har redan använts för en annan begäran. Använd en ny nyckel för en ny begäran.
429 Too Many Requests – Rate limit exceeded (per credential, per company or per address). Wait Retry-After seconds.
-
rate_limitedOver the limitFör många anrop. Försök igen om 23 sekunder.
Code samples
curl -X POST "https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54/issue" \
-H "Authorization: Bearer $NONOX_TOKEN" \
-H "Accept: application/json" \
-H "Idempotency-Key: $(uuidgen)"use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;
$response = Http::withToken(config('services.nonox.token'))
->acceptJson()
->withHeaders(['Idempotency-Key' => (string) Str::uuid()])
->post('https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54/issue');
$response->throw();
$data = $response->json('data');$client = new \GuzzleHttp\Client(['timeout' => 30]);
$response = $client->request('POST', 'https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54/issue', [
'headers' => [
'Authorization' => 'Bearer '.getenv('NONOX_TOKEN'),
'Accept' => 'application/json',
'Idempotency-Key' => bin2hex(random_bytes(16)),
],
]);
$data = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR)['data'];const response = await fetch('https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54/issue', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.NONOX_TOKEN}`,
Accept: 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
});
if (!response.ok) {
const problem = await response.json();
throw new Error(`${problem.code}: ${problem.detail}`);
}
const { data } = await response.json();import os
import uuid
import requests
response = requests.post(
"https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54/issue",
headers={
"Authorization": f"Bearer {os.environ['NONOX_TOKEN']}",
"Accept": "application/json",
"Idempotency-Key": str(uuid.uuid4()),
},
timeout=30,
)
response.raise_for_status()
data = response.json()["data"]Responses · 200
{
"data": {
"id": "5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54",
"number": 1042,
"kind": "INVOICE",
"status": "PAID",
"credits_invoice_id": null,
"customer_id": 18,
"customer": {
"number": 1004,
"name": "Kund Exempel AB",
"org_number": "559900-4560",
"vat_number": "SE559900456001",
"email": "faktura@kund.example.se",
"address": {
"line1": "Kundvägen 5",
"line2": null,
"postal_code": "222 33",
"city": "Exempelby",
"country": "SE"
}
},
"invoice_date": "2026-03-02",
"due_date": "2026-04-01",
"delivery_date": null,
"your_reference": "Anna Exempel",
"our_reference": null,
"notes": null,
"reverse_charge": false,
"foreign_sale": null,
"tax_reduction": null,
"tax_reduction_ore": 0,
"property_designation": null,
"currency": "SEK",
"net_ore": 190000,
"vat_ore": 47500,
"rounding_ore": 0,
"total_ore": 237500,
"paid_ore": 237500,
"remaining_ore": 0,
"ocr": "104257",
"voucher_id": "1d2e3f4a-5b6c-4d7e-8f9a-0b1c2d3e4f5a",
"issued_at": "2026-03-02T10:45:12+01:00",
"sent_at": "2026-03-02T10:45:12+01:00",
"sent_to": "faktura@kund.example.se",
"rows": [
{
"article": "TIM",
"description": "Konsulttimme",
"quantity": "2",
"unit": "h",
"unit_price_ore": 95000,
"discount_bp": 0,
"vat_rate": 2500,
"account": 3001,
"net_ore": 190000,
"labour": false
}
],
"payments": [
{
"id": 88,
"invoice_id": "5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54",
"paid_on": "2026-03-28",
"amount_ore": 237500,
"currency": "SEK",
"account": 1930,
"voucher_id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"created_at": "2026-03-28T09:12:00+01:00",
"updated_at": "2026-03-28T09:12:00+01:00"
}
],
"created_at": "2026-03-02T10:45:12+01:00",
"updated_at": "2026-03-28T09:12:00+01:00"
}
}Error
4003 examples
{
"type": "urn:nonox:problem:idempotency_key_required",
"title": "Bad Request",
"status": 400,
"code": "idempotency_key_required",
"detail": "Skicka en unik Idempotency-Key (till exempel ett UUID) med varje POST, så att ett nytt försök aldrig bokför två gånger.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:idempotency_key_invalid",
"title": "Bad Request",
"status": 400,
"code": "idempotency_key_invalid",
"detail": "Idempotency-Key ska vara 1–255 synliga ASCII-tecken.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:invalid_json",
"title": "Bad Request",
"status": 400,
"code": "invalid_json",
"detail": "Kroppen är inte giltig JSON (ett objekt).",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4011 example
{
"type": "urn:nonox:problem:unauthenticated",
"title": "Unauthorized",
"status": 401,
"code": "unauthenticated",
"detail": "Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4035 examples
{
"type": "urn:nonox:problem:insufficient_scope",
"title": "Forbidden",
"status": 403,
"code": "insufficient_scope",
"detail": "Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
"required_scopes": [
"vouchers:post"
]
}{
"type": "urn:nonox:problem:forbidden",
"title": "Forbidden",
"status": 403,
"code": "forbidden",
"detail": "Behörighet saknas för det här.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:ip_not_allowed",
"title": "Forbidden",
"status": 403,
"code": "ip_not_allowed",
"detail": "Företaget tillåter inte anrop från den här adressen.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:company_archived",
"title": "Forbidden",
"status": 403,
"code": "company_archived",
"detail": "Företaget är arkiverat och kan bara läsas.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:app_not_allowed",
"title": "Forbidden",
"status": 403,
"code": "app_not_allowed",
"detail": "Företaget tillåter inte längre den här appen.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4041 example
{
"type": "urn:nonox:problem:not_found",
"title": "Not Found",
"status": 404,
"code": "not_found",
"detail": "Det du söker finns inte.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4091 example
{
"type": "urn:nonox:problem:idempotency_in_progress",
"title": "Conflict",
"status": 409,
"code": "idempotency_in_progress",
"detail": "En begäran med samma Idempotency-Key pågår. Vänta och försök igen.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4151 example
{
"type": "urn:nonox:problem:unsupported_media_type",
"title": "Unsupported Media Type",
"status": 415,
"code": "unsupported_media_type",
"detail": "Skicka JSON (application/json).",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4222 examples
{
"type": "urn:nonox:problem:validation_failed",
"title": "Unprocessable Content",
"status": 422,
"code": "validation_failed",
"detail": "Uppgifterna kunde inte godtas. Se errors.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
"errors": {
"rows": [
"Verifikationen balanserar inte: debet och kredit skiljer sig åt."
],
"voucher_date": [
"Det finns inget räkenskapsår som omfattar 2031-01-01."
]
}
}{
"type": "urn:nonox:problem:idempotency_key_reused",
"title": "Unprocessable Content",
"status": 422,
"code": "idempotency_key_reused",
"detail": "Idempotency-Key har redan använts för en annan begäran. Använd en ny nyckel för en ny begäran.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4291 example
{
"type": "urn:nonox:problem:rate_limited",
"title": "Too Many Requests",
"status": 429,
"code": "rate_limited",
"detail": "För många anrop. Försök igen om 23 sekunder.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}E-mail an issued invoice
POST
/invoices/{invoice}/send
sendInvoice
E-mails the issued invoice as a PDF to `email` or to the customer's address, and fires invoice.sent. A test company never e-mails anything. Same Action as the app (SendInvoice).
Scope
Parameters
-
invoicestring (uuid) path requiredInvoice id (UUID, not the invoice number).
-
Idempotency-Keystring header requiredRequired on every POST. A unique value per intended operation (a UUID v4 is ideal), 1–255 visible ASCII characters. Kept 24 hours per credential: the same key with the same request returns the stored response (Idempotent-Replayed: true); with a different request 422 idempotency_key_reused; while the first is still running 409. Server errors (5xx) are not stored, so retry with the same key.
Request body
application/jsonSendInvoiceInput
-
emailstring (email) nullableDefault: the customer's e-mail on the invoice.
Responses
200 OK – The invoice, with sent_at and sent_to.
application/jsonobject
-
dataInvoice required34 fields
-
idstring (uuid) -
numberinteger nullableGapless invoice number, null while a draft.
-
kindstring -
statusstringOpen enum.
-
credits_invoice_idstring (uuid) nullable -
customer_idinteger -
customerobjectThe customer as on the invoice (frozen when issued). Never a personal number.
6 fields
-
numberinteger nullable -
namestring nullable -
org_numberstring nullable -
vat_numberstring nullable -
emailstring nullable -
addressobject5 fields
-
line1string nullable -
line2string nullable -
postal_codestring nullable -
citystring nullable -
countrystring nullable
-
-
-
invoice_datestring (date) -
due_datestring (date) -
delivery_datestring (date) nullable -
your_referencestring nullable -
our_referencestring nullable -
notesstring nullable -
reverse_chargeboolean -
foreign_salestring nullable -
tax_reductionstring nullableROT or RUT.
-
tax_reduction_oreinteger -
property_designationstring nullable -
currencystring -
net_oreinteger -
vat_oreinteger -
rounding_oreintegerÖresavrundning to whole kronor.
-
total_oreinteger -
paid_oreinteger -
remaining_oreinteger -
ocrstring nullable -
voucher_idstring (uuid) nullable -
issued_atstring (date-time) nullable -
sent_atstring (date-time) nullable -
sent_tostring nullable -
rowsarray<InvoiceRow>10 fields · each item
-
articlestring nullable -
descriptionstring -
quantitystringDecimal string, up to three decimals; negative on credit invoices.
-
unitstring -
unit_price_oreinteger -
discount_bpintegerDiscount in basis points (1000 is 10 %).
-
vat_rateinteger -
accountinteger nullable -
net_oreinteger -
labourbooleanLabour cost (ROT/RUT).
-
-
paymentsarray<InvoicePayment>9 fields · each item
-
idinteger -
invoice_idstring (uuid) -
paid_onstring (date) -
amount_oreinteger -
currencystring -
accountinteger nullableBank account the money came in on.
-
voucher_idstring (uuid) -
created_atstring (date-time) -
updated_atstring (date-time)
-
-
created_atstring (date-time) -
updated_atstring (date-time)
-
400 Bad Request – Bad request: missing or invalid Idempotency-Key, or a body that is not a JSON object.
-
idempotency_key_requiredNo Idempotency-Key on a POSTSkicka en unik Idempotency-Key (till exempel ett UUID) med varje POST, så att ett nytt försök aldrig bokför två gånger.
-
idempotency_key_invalidIdempotency-Key too long or not visible ASCIIIdempotency-Key ska vara 1–255 synliga ASCII-tecken.
-
invalid_jsonMalformed JSONKroppen är inte giltig JSON (ett objekt).
401 Unauthorized – Missing, invalid, expired or revoked token or API key. Also returned when the person behind the credential has left the company (an OAuth grant is then revoked for good).
-
unauthenticatedNo valid credentialNyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.
403 Forbidden – The credential may not do this: a scope is missing, the granting person no longer has the permission, the address is not allowed, the company is archived (read-only) or no longer allows the app.
-
insufficient_scopeScope missing or permission lostNyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.
-
forbiddenThe action refuses (for example changing a posted voucher)Behörighet saknas för det här.
-
ip_not_allowedOutside the IP allowlistFöretaget tillåter inte anrop från den här adressen.
-
company_archivedWrite to an archived companyFöretaget är arkiverat och kan bara läsas.
-
app_not_allowedThe company no longer allows the appFöretaget tillåter inte längre den här appen.
404 Not Found – Not found. Also the answer for another company's ids (existence is never revealed) and for every call while NONOX Connect is turned off for the company.
-
not_foundUnknown id, other company's id, or module offDet du söker finns inte.
409 Conflict – A request with the same Idempotency-Key is still running.
-
idempotency_in_progressSame key, first request not finishedEn begäran med samma Idempotency-Key pågår. Vänta och försök igen.
415 Unsupported Media Type – The body is not application/json (or multipart/form-data where a file is accepted).
-
unsupported_media_typeWrong Content-TypeSkicka JSON (application/json).
422 Unprocessable Content – Validation failed, or the Idempotency-Key was already used for a different request.
-
validation_failedField errorsUppgifterna kunde inte godtas. Se errors.
-
idempotency_key_reusedSame key, different bodyIdempotency-Key har redan använts för en annan begäran. Använd en ny nyckel för en ny begäran.
429 Too Many Requests – Rate limit exceeded (per credential, per company or per address). Wait Retry-After seconds.
-
rate_limitedOver the limitFör många anrop. Försök igen om 23 sekunder.
Code samples
curl -X POST "https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54/send" \
-H "Authorization: Bearer $NONOX_TOKEN" \
-H "Accept: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"email": "faktura@kund.example.se"
}'use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;
$response = Http::withToken(config('services.nonox.token'))
->acceptJson()
->withHeaders(['Idempotency-Key' => (string) Str::uuid()])
->post('https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54/send', [
'email' => 'faktura@kund.example.se',
]);
$response->throw();
$data = $response->json('data');$client = new \GuzzleHttp\Client(['timeout' => 30]);
$response = $client->request('POST', 'https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54/send', [
'headers' => [
'Authorization' => 'Bearer '.getenv('NONOX_TOKEN'),
'Accept' => 'application/json',
'Idempotency-Key' => bin2hex(random_bytes(16)),
],
'json' => [
'email' => 'faktura@kund.example.se',
],
]);
$data = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR)['data'];const response = await fetch('https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54/send', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.NONOX_TOKEN}`,
Accept: 'application/json',
'Idempotency-Key': crypto.randomUUID(),
'Content-Type': 'application/json',
},
body: JSON.stringify({
"email": "faktura@kund.example.se"
}),
});
if (!response.ok) {
const problem = await response.json();
throw new Error(`${problem.code}: ${problem.detail}`);
}
const { data } = await response.json();import os
import uuid
import requests
response = requests.post(
"https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54/send",
headers={
"Authorization": f"Bearer {os.environ['NONOX_TOKEN']}",
"Accept": "application/json",
"Idempotency-Key": str(uuid.uuid4()),
},
json={
"email": "faktura@kund.example.se",
},
timeout=30,
)
response.raise_for_status()
data = response.json()["data"]Responses · 200
{
"data": {
"id": "5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54",
"number": 1042,
"kind": "INVOICE",
"status": "PAID",
"credits_invoice_id": null,
"customer_id": 18,
"customer": {
"number": 1004,
"name": "Kund Exempel AB",
"org_number": "559900-4560",
"vat_number": "SE559900456001",
"email": "faktura@kund.example.se",
"address": {
"line1": "Kundvägen 5",
"line2": null,
"postal_code": "222 33",
"city": "Exempelby",
"country": "SE"
}
},
"invoice_date": "2026-03-02",
"due_date": "2026-04-01",
"delivery_date": null,
"your_reference": "Anna Exempel",
"our_reference": null,
"notes": null,
"reverse_charge": false,
"foreign_sale": null,
"tax_reduction": null,
"tax_reduction_ore": 0,
"property_designation": null,
"currency": "SEK",
"net_ore": 190000,
"vat_ore": 47500,
"rounding_ore": 0,
"total_ore": 237500,
"paid_ore": 237500,
"remaining_ore": 0,
"ocr": "104257",
"voucher_id": "1d2e3f4a-5b6c-4d7e-8f9a-0b1c2d3e4f5a",
"issued_at": "2026-03-02T10:45:12+01:00",
"sent_at": "2026-03-02T10:45:12+01:00",
"sent_to": "faktura@kund.example.se",
"rows": [
{
"article": "TIM",
"description": "Konsulttimme",
"quantity": "2",
"unit": "h",
"unit_price_ore": 95000,
"discount_bp": 0,
"vat_rate": 2500,
"account": 3001,
"net_ore": 190000,
"labour": false
}
],
"payments": [
{
"id": 88,
"invoice_id": "5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54",
"paid_on": "2026-03-28",
"amount_ore": 237500,
"currency": "SEK",
"account": 1930,
"voucher_id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"created_at": "2026-03-28T09:12:00+01:00",
"updated_at": "2026-03-28T09:12:00+01:00"
}
],
"created_at": "2026-03-02T10:45:12+01:00",
"updated_at": "2026-03-28T09:12:00+01:00"
}
}Error
4003 examples
{
"type": "urn:nonox:problem:idempotency_key_required",
"title": "Bad Request",
"status": 400,
"code": "idempotency_key_required",
"detail": "Skicka en unik Idempotency-Key (till exempel ett UUID) med varje POST, så att ett nytt försök aldrig bokför två gånger.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:idempotency_key_invalid",
"title": "Bad Request",
"status": 400,
"code": "idempotency_key_invalid",
"detail": "Idempotency-Key ska vara 1–255 synliga ASCII-tecken.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:invalid_json",
"title": "Bad Request",
"status": 400,
"code": "invalid_json",
"detail": "Kroppen är inte giltig JSON (ett objekt).",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4011 example
{
"type": "urn:nonox:problem:unauthenticated",
"title": "Unauthorized",
"status": 401,
"code": "unauthenticated",
"detail": "Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4035 examples
{
"type": "urn:nonox:problem:insufficient_scope",
"title": "Forbidden",
"status": 403,
"code": "insufficient_scope",
"detail": "Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
"required_scopes": [
"vouchers:post"
]
}{
"type": "urn:nonox:problem:forbidden",
"title": "Forbidden",
"status": 403,
"code": "forbidden",
"detail": "Behörighet saknas för det här.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:ip_not_allowed",
"title": "Forbidden",
"status": 403,
"code": "ip_not_allowed",
"detail": "Företaget tillåter inte anrop från den här adressen.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:company_archived",
"title": "Forbidden",
"status": 403,
"code": "company_archived",
"detail": "Företaget är arkiverat och kan bara läsas.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:app_not_allowed",
"title": "Forbidden",
"status": 403,
"code": "app_not_allowed",
"detail": "Företaget tillåter inte längre den här appen.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4041 example
{
"type": "urn:nonox:problem:not_found",
"title": "Not Found",
"status": 404,
"code": "not_found",
"detail": "Det du söker finns inte.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4091 example
{
"type": "urn:nonox:problem:idempotency_in_progress",
"title": "Conflict",
"status": 409,
"code": "idempotency_in_progress",
"detail": "En begäran med samma Idempotency-Key pågår. Vänta och försök igen.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4151 example
{
"type": "urn:nonox:problem:unsupported_media_type",
"title": "Unsupported Media Type",
"status": 415,
"code": "unsupported_media_type",
"detail": "Skicka JSON (application/json).",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4222 examples
{
"type": "urn:nonox:problem:validation_failed",
"title": "Unprocessable Content",
"status": 422,
"code": "validation_failed",
"detail": "Uppgifterna kunde inte godtas. Se errors.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
"errors": {
"rows": [
"Verifikationen balanserar inte: debet och kredit skiljer sig åt."
],
"voucher_date": [
"Det finns inget räkenskapsår som omfattar 2031-01-01."
]
}
}{
"type": "urn:nonox:problem:idempotency_key_reused",
"title": "Unprocessable Content",
"status": 422,
"code": "idempotency_key_reused",
"detail": "Idempotency-Key har redan använts för en annan begäran. Använd en ny nyckel för en ny begäran.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4291 example
{
"type": "urn:nonox:problem:rate_limited",
"title": "Too Many Requests",
"status": 429,
"code": "rate_limited",
"detail": "För många anrop. Försök igen om 23 sekunder.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}Start a credit invoice
POST
/invoices/{invoice}/credit
creditInvoice
Creates a draft credit invoice for the whole of an unpaid invoice, with the same rows and negative quantities. It takes effect when issued with /issue, which closes both. Same Action as the app (CreditInvoice).
Scope
Parameters
-
invoicestring (uuid) path requiredInvoice id (UUID, not the invoice number).
-
Idempotency-Keystring header requiredRequired on every POST. A unique value per intended operation (a UUID v4 is ideal), 1–255 visible ASCII characters. Kept 24 hours per credential: the same key with the same request returns the stored response (Idempotent-Replayed: true); with a different request 422 idempotency_key_reused; while the first is still running 409. Server errors (5xx) are not stored, so retry with the same key.
Responses
201 Created – The credit invoice draft.
application/jsonobject
-
dataInvoice required34 fields
-
idstring (uuid) -
numberinteger nullableGapless invoice number, null while a draft.
-
kindstring -
statusstringOpen enum.
-
credits_invoice_idstring (uuid) nullable -
customer_idinteger -
customerobjectThe customer as on the invoice (frozen when issued). Never a personal number.
6 fields
-
numberinteger nullable -
namestring nullable -
org_numberstring nullable -
vat_numberstring nullable -
emailstring nullable -
addressobject5 fields
-
line1string nullable -
line2string nullable -
postal_codestring nullable -
citystring nullable -
countrystring nullable
-
-
-
invoice_datestring (date) -
due_datestring (date) -
delivery_datestring (date) nullable -
your_referencestring nullable -
our_referencestring nullable -
notesstring nullable -
reverse_chargeboolean -
foreign_salestring nullable -
tax_reductionstring nullableROT or RUT.
-
tax_reduction_oreinteger -
property_designationstring nullable -
currencystring -
net_oreinteger -
vat_oreinteger -
rounding_oreintegerÖresavrundning to whole kronor.
-
total_oreinteger -
paid_oreinteger -
remaining_oreinteger -
ocrstring nullable -
voucher_idstring (uuid) nullable -
issued_atstring (date-time) nullable -
sent_atstring (date-time) nullable -
sent_tostring nullable -
rowsarray<InvoiceRow>10 fields · each item
-
articlestring nullable -
descriptionstring -
quantitystringDecimal string, up to three decimals; negative on credit invoices.
-
unitstring -
unit_price_oreinteger -
discount_bpintegerDiscount in basis points (1000 is 10 %).
-
vat_rateinteger -
accountinteger nullable -
net_oreinteger -
labourbooleanLabour cost (ROT/RUT).
-
-
paymentsarray<InvoicePayment>9 fields · each item
-
idinteger -
invoice_idstring (uuid) -
paid_onstring (date) -
amount_oreinteger -
currencystring -
accountinteger nullableBank account the money came in on.
-
voucher_idstring (uuid) -
created_atstring (date-time) -
updated_atstring (date-time)
-
-
created_atstring (date-time) -
updated_atstring (date-time)
-
400 Bad Request – Bad request: missing or invalid Idempotency-Key, or a body that is not a JSON object.
-
idempotency_key_requiredNo Idempotency-Key on a POSTSkicka en unik Idempotency-Key (till exempel ett UUID) med varje POST, så att ett nytt försök aldrig bokför två gånger.
-
idempotency_key_invalidIdempotency-Key too long or not visible ASCIIIdempotency-Key ska vara 1–255 synliga ASCII-tecken.
-
invalid_jsonMalformed JSONKroppen är inte giltig JSON (ett objekt).
401 Unauthorized – Missing, invalid, expired or revoked token or API key. Also returned when the person behind the credential has left the company (an OAuth grant is then revoked for good).
-
unauthenticatedNo valid credentialNyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.
403 Forbidden – The credential may not do this: a scope is missing, the granting person no longer has the permission, the address is not allowed, the company is archived (read-only) or no longer allows the app.
-
insufficient_scopeScope missing or permission lostNyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.
-
forbiddenThe action refuses (for example changing a posted voucher)Behörighet saknas för det här.
-
ip_not_allowedOutside the IP allowlistFöretaget tillåter inte anrop från den här adressen.
-
company_archivedWrite to an archived companyFöretaget är arkiverat och kan bara läsas.
-
app_not_allowedThe company no longer allows the appFöretaget tillåter inte längre den här appen.
404 Not Found – Not found. Also the answer for another company's ids (existence is never revealed) and for every call while NONOX Connect is turned off for the company.
-
not_foundUnknown id, other company's id, or module offDet du söker finns inte.
409 Conflict – A request with the same Idempotency-Key is still running.
-
idempotency_in_progressSame key, first request not finishedEn begäran med samma Idempotency-Key pågår. Vänta och försök igen.
415 Unsupported Media Type – The body is not application/json (or multipart/form-data where a file is accepted).
-
unsupported_media_typeWrong Content-TypeSkicka JSON (application/json).
422 Unprocessable Content – Validation failed, or the Idempotency-Key was already used for a different request.
-
validation_failedField errorsUppgifterna kunde inte godtas. Se errors.
-
idempotency_key_reusedSame key, different bodyIdempotency-Key har redan använts för en annan begäran. Använd en ny nyckel för en ny begäran.
429 Too Many Requests – Rate limit exceeded (per credential, per company or per address). Wait Retry-After seconds.
-
rate_limitedOver the limitFör många anrop. Försök igen om 23 sekunder.
Code samples
curl -X POST "https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54/credit" \
-H "Authorization: Bearer $NONOX_TOKEN" \
-H "Accept: application/json" \
-H "Idempotency-Key: $(uuidgen)"use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;
$response = Http::withToken(config('services.nonox.token'))
->acceptJson()
->withHeaders(['Idempotency-Key' => (string) Str::uuid()])
->post('https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54/credit');
$response->throw();
$data = $response->json('data');$client = new \GuzzleHttp\Client(['timeout' => 30]);
$response = $client->request('POST', 'https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54/credit', [
'headers' => [
'Authorization' => 'Bearer '.getenv('NONOX_TOKEN'),
'Accept' => 'application/json',
'Idempotency-Key' => bin2hex(random_bytes(16)),
],
]);
$data = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR)['data'];const response = await fetch('https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54/credit', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.NONOX_TOKEN}`,
Accept: 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
});
if (!response.ok) {
const problem = await response.json();
throw new Error(`${problem.code}: ${problem.detail}`);
}
const { data } = await response.json();import os
import uuid
import requests
response = requests.post(
"https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54/credit",
headers={
"Authorization": f"Bearer {os.environ['NONOX_TOKEN']}",
"Accept": "application/json",
"Idempotency-Key": str(uuid.uuid4()),
},
timeout=30,
)
response.raise_for_status()
data = response.json()["data"]Responses · 201
{
"data": {
"id": "5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54",
"number": 1042,
"kind": "INVOICE",
"status": "PAID",
"credits_invoice_id": null,
"customer_id": 18,
"customer": {
"number": 1004,
"name": "Kund Exempel AB",
"org_number": "559900-4560",
"vat_number": "SE559900456001",
"email": "faktura@kund.example.se",
"address": {
"line1": "Kundvägen 5",
"line2": null,
"postal_code": "222 33",
"city": "Exempelby",
"country": "SE"
}
},
"invoice_date": "2026-03-02",
"due_date": "2026-04-01",
"delivery_date": null,
"your_reference": "Anna Exempel",
"our_reference": null,
"notes": null,
"reverse_charge": false,
"foreign_sale": null,
"tax_reduction": null,
"tax_reduction_ore": 0,
"property_designation": null,
"currency": "SEK",
"net_ore": 190000,
"vat_ore": 47500,
"rounding_ore": 0,
"total_ore": 237500,
"paid_ore": 237500,
"remaining_ore": 0,
"ocr": "104257",
"voucher_id": "1d2e3f4a-5b6c-4d7e-8f9a-0b1c2d3e4f5a",
"issued_at": "2026-03-02T10:45:12+01:00",
"sent_at": "2026-03-02T10:45:12+01:00",
"sent_to": "faktura@kund.example.se",
"rows": [
{
"article": "TIM",
"description": "Konsulttimme",
"quantity": "2",
"unit": "h",
"unit_price_ore": 95000,
"discount_bp": 0,
"vat_rate": 2500,
"account": 3001,
"net_ore": 190000,
"labour": false
}
],
"payments": [
{
"id": 88,
"invoice_id": "5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54",
"paid_on": "2026-03-28",
"amount_ore": 237500,
"currency": "SEK",
"account": 1930,
"voucher_id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"created_at": "2026-03-28T09:12:00+01:00",
"updated_at": "2026-03-28T09:12:00+01:00"
}
],
"created_at": "2026-03-02T10:45:12+01:00",
"updated_at": "2026-03-28T09:12:00+01:00"
}
}Error
4003 examples
{
"type": "urn:nonox:problem:idempotency_key_required",
"title": "Bad Request",
"status": 400,
"code": "idempotency_key_required",
"detail": "Skicka en unik Idempotency-Key (till exempel ett UUID) med varje POST, så att ett nytt försök aldrig bokför två gånger.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:idempotency_key_invalid",
"title": "Bad Request",
"status": 400,
"code": "idempotency_key_invalid",
"detail": "Idempotency-Key ska vara 1–255 synliga ASCII-tecken.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:invalid_json",
"title": "Bad Request",
"status": 400,
"code": "invalid_json",
"detail": "Kroppen är inte giltig JSON (ett objekt).",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4011 example
{
"type": "urn:nonox:problem:unauthenticated",
"title": "Unauthorized",
"status": 401,
"code": "unauthenticated",
"detail": "Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4035 examples
{
"type": "urn:nonox:problem:insufficient_scope",
"title": "Forbidden",
"status": 403,
"code": "insufficient_scope",
"detail": "Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
"required_scopes": [
"vouchers:post"
]
}{
"type": "urn:nonox:problem:forbidden",
"title": "Forbidden",
"status": 403,
"code": "forbidden",
"detail": "Behörighet saknas för det här.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:ip_not_allowed",
"title": "Forbidden",
"status": 403,
"code": "ip_not_allowed",
"detail": "Företaget tillåter inte anrop från den här adressen.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:company_archived",
"title": "Forbidden",
"status": 403,
"code": "company_archived",
"detail": "Företaget är arkiverat och kan bara läsas.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:app_not_allowed",
"title": "Forbidden",
"status": 403,
"code": "app_not_allowed",
"detail": "Företaget tillåter inte längre den här appen.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4041 example
{
"type": "urn:nonox:problem:not_found",
"title": "Not Found",
"status": 404,
"code": "not_found",
"detail": "Det du söker finns inte.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4091 example
{
"type": "urn:nonox:problem:idempotency_in_progress",
"title": "Conflict",
"status": 409,
"code": "idempotency_in_progress",
"detail": "En begäran med samma Idempotency-Key pågår. Vänta och försök igen.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4151 example
{
"type": "urn:nonox:problem:unsupported_media_type",
"title": "Unsupported Media Type",
"status": 415,
"code": "unsupported_media_type",
"detail": "Skicka JSON (application/json).",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4222 examples
{
"type": "urn:nonox:problem:validation_failed",
"title": "Unprocessable Content",
"status": 422,
"code": "validation_failed",
"detail": "Uppgifterna kunde inte godtas. Se errors.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
"errors": {
"rows": [
"Verifikationen balanserar inte: debet och kredit skiljer sig åt."
],
"voucher_date": [
"Det finns inget räkenskapsår som omfattar 2031-01-01."
]
}
}{
"type": "urn:nonox:problem:idempotency_key_reused",
"title": "Unprocessable Content",
"status": 422,
"code": "idempotency_key_reused",
"detail": "Idempotency-Key har redan använts för en annan begäran. Använd en ny nyckel för en ny begäran.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4291 example
{
"type": "urn:nonox:problem:rate_limited",
"title": "Too Many Requests",
"status": 429,
"code": "rate_limited",
"detail": "För många anrop. Försök igen om 23 sekunder.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}Register a payment
POST
/invoices/{invoice}/payments
registerInvoicePayment
Registers money received, booked in series C; the invoice is PAID when nothing remains (and invoice.paid is sent). More than what remains answers 422. Books a voucher as the person behind the credential, so the credential also needs vouchers:create and vouchers:post. Same Action as the app (RegisterPayment).
Scope
payments:create + vouchers:create + vouchers:post
Parameters
-
invoicestring (uuid) path requiredInvoice id (UUID, not the invoice number).
-
Idempotency-Keystring header requiredRequired on every POST. A unique value per intended operation (a UUID v4 is ideal), 1–255 visible ASCII characters. Kept 24 hours per credential: the same key with the same request returns the stored response (Idempotent-Replayed: true); with a different request 422 idempotency_key_reused; while the first is still running 409. Server errors (5xx) are not stored, so retry with the same key.
Request body
application/jsonPaymentInput required
-
paid_onstring (date) required -
amount_oreinteger required -
accountinteger nullableBank account; default 1930.
Responses
201 Created – The payment.
application/jsonobject
-
dataInvoicePayment required9 fields
-
idinteger -
invoice_idstring (uuid) -
paid_onstring (date) -
amount_oreinteger -
currencystring -
accountinteger nullableBank account the money came in on.
-
voucher_idstring (uuid) -
created_atstring (date-time) -
updated_atstring (date-time)
-
400 Bad Request – Bad request: missing or invalid Idempotency-Key, or a body that is not a JSON object.
-
idempotency_key_requiredNo Idempotency-Key on a POSTSkicka en unik Idempotency-Key (till exempel ett UUID) med varje POST, så att ett nytt försök aldrig bokför två gånger.
-
idempotency_key_invalidIdempotency-Key too long or not visible ASCIIIdempotency-Key ska vara 1–255 synliga ASCII-tecken.
-
invalid_jsonMalformed JSONKroppen är inte giltig JSON (ett objekt).
401 Unauthorized – Missing, invalid, expired or revoked token or API key. Also returned when the person behind the credential has left the company (an OAuth grant is then revoked for good).
-
unauthenticatedNo valid credentialNyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.
403 Forbidden – The credential may not do this: a scope is missing, the granting person no longer has the permission, the address is not allowed, the company is archived (read-only) or no longer allows the app.
-
insufficient_scopeScope missing or permission lostNyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.
-
forbiddenThe action refuses (for example changing a posted voucher)Behörighet saknas för det här.
-
ip_not_allowedOutside the IP allowlistFöretaget tillåter inte anrop från den här adressen.
-
company_archivedWrite to an archived companyFöretaget är arkiverat och kan bara läsas.
-
app_not_allowedThe company no longer allows the appFöretaget tillåter inte längre den här appen.
404 Not Found – Not found. Also the answer for another company's ids (existence is never revealed) and for every call while NONOX Connect is turned off for the company.
-
not_foundUnknown id, other company's id, or module offDet du söker finns inte.
409 Conflict – A request with the same Idempotency-Key is still running.
-
idempotency_in_progressSame key, first request not finishedEn begäran med samma Idempotency-Key pågår. Vänta och försök igen.
415 Unsupported Media Type – The body is not application/json (or multipart/form-data where a file is accepted).
-
unsupported_media_typeWrong Content-TypeSkicka JSON (application/json).
422 Unprocessable Content – Validation failed, or the Idempotency-Key was already used for a different request.
-
validation_failedField errorsUppgifterna kunde inte godtas. Se errors.
-
idempotency_key_reusedSame key, different bodyIdempotency-Key har redan använts för en annan begäran. Använd en ny nyckel för en ny begäran.
429 Too Many Requests – Rate limit exceeded (per credential, per company or per address). Wait Retry-After seconds.
-
rate_limitedOver the limitFör många anrop. Försök igen om 23 sekunder.
Code samples
curl -X POST "https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54/payments" \
-H "Authorization: Bearer $NONOX_TOKEN" \
-H "Accept: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"paid_on": "2026-03-28",
"amount_ore": 237500
}'use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;
$response = Http::withToken(config('services.nonox.token'))
->acceptJson()
->withHeaders(['Idempotency-Key' => (string) Str::uuid()])
->post('https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54/payments', [
'paid_on' => '2026-03-28',
'amount_ore' => 237500,
]);
$response->throw();
$data = $response->json('data');$client = new \GuzzleHttp\Client(['timeout' => 30]);
$response = $client->request('POST', 'https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54/payments', [
'headers' => [
'Authorization' => 'Bearer '.getenv('NONOX_TOKEN'),
'Accept' => 'application/json',
'Idempotency-Key' => bin2hex(random_bytes(16)),
],
'json' => [
'paid_on' => '2026-03-28',
'amount_ore' => 237500,
],
]);
$data = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR)['data'];const response = await fetch('https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54/payments', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.NONOX_TOKEN}`,
Accept: 'application/json',
'Idempotency-Key': crypto.randomUUID(),
'Content-Type': 'application/json',
},
body: JSON.stringify({
"paid_on": "2026-03-28",
"amount_ore": 237500
}),
});
if (!response.ok) {
const problem = await response.json();
throw new Error(`${problem.code}: ${problem.detail}`);
}
const { data } = await response.json();import os
import uuid
import requests
response = requests.post(
"https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54/payments",
headers={
"Authorization": f"Bearer {os.environ['NONOX_TOKEN']}",
"Accept": "application/json",
"Idempotency-Key": str(uuid.uuid4()),
},
json={
"paid_on": "2026-03-28",
"amount_ore": 237500,
},
timeout=30,
)
response.raise_for_status()
data = response.json()["data"]Responses · 201
{
"data": {
"id": 88,
"invoice_id": "5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54",
"paid_on": "2026-03-28",
"amount_ore": 237500,
"currency": "SEK",
"account": 1930,
"voucher_id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"created_at": "2026-03-28T09:12:00+01:00",
"updated_at": "2026-03-28T09:12:00+01:00"
}
}Error
4003 examples
{
"type": "urn:nonox:problem:idempotency_key_required",
"title": "Bad Request",
"status": 400,
"code": "idempotency_key_required",
"detail": "Skicka en unik Idempotency-Key (till exempel ett UUID) med varje POST, så att ett nytt försök aldrig bokför två gånger.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:idempotency_key_invalid",
"title": "Bad Request",
"status": 400,
"code": "idempotency_key_invalid",
"detail": "Idempotency-Key ska vara 1–255 synliga ASCII-tecken.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:invalid_json",
"title": "Bad Request",
"status": 400,
"code": "invalid_json",
"detail": "Kroppen är inte giltig JSON (ett objekt).",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4011 example
{
"type": "urn:nonox:problem:unauthenticated",
"title": "Unauthorized",
"status": 401,
"code": "unauthenticated",
"detail": "Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4035 examples
{
"type": "urn:nonox:problem:insufficient_scope",
"title": "Forbidden",
"status": 403,
"code": "insufficient_scope",
"detail": "Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
"required_scopes": [
"vouchers:post"
]
}{
"type": "urn:nonox:problem:forbidden",
"title": "Forbidden",
"status": 403,
"code": "forbidden",
"detail": "Behörighet saknas för det här.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:ip_not_allowed",
"title": "Forbidden",
"status": 403,
"code": "ip_not_allowed",
"detail": "Företaget tillåter inte anrop från den här adressen.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:company_archived",
"title": "Forbidden",
"status": 403,
"code": "company_archived",
"detail": "Företaget är arkiverat och kan bara läsas.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:app_not_allowed",
"title": "Forbidden",
"status": 403,
"code": "app_not_allowed",
"detail": "Företaget tillåter inte längre den här appen.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4041 example
{
"type": "urn:nonox:problem:not_found",
"title": "Not Found",
"status": 404,
"code": "not_found",
"detail": "Det du söker finns inte.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4091 example
{
"type": "urn:nonox:problem:idempotency_in_progress",
"title": "Conflict",
"status": 409,
"code": "idempotency_in_progress",
"detail": "En begäran med samma Idempotency-Key pågår. Vänta och försök igen.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4151 example
{
"type": "urn:nonox:problem:unsupported_media_type",
"title": "Unsupported Media Type",
"status": 415,
"code": "unsupported_media_type",
"detail": "Skicka JSON (application/json).",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4222 examples
{
"type": "urn:nonox:problem:validation_failed",
"title": "Unprocessable Content",
"status": 422,
"code": "validation_failed",
"detail": "Uppgifterna kunde inte godtas. Se errors.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
"errors": {
"rows": [
"Verifikationen balanserar inte: debet och kredit skiljer sig åt."
],
"voucher_date": [
"Det finns inget räkenskapsår som omfattar 2031-01-01."
]
}
}{
"type": "urn:nonox:problem:idempotency_key_reused",
"title": "Unprocessable Content",
"status": 422,
"code": "idempotency_key_reused",
"detail": "Idempotency-Key har redan använts för en annan begäran. Använd en ny nyckel för en ny begäran.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4291 example
{
"type": "urn:nonox:problem:rate_limited",
"title": "Too Many Requests",
"status": 429,
"code": "rate_limited",
"detail": "För många anrop. Försök igen om 23 sekunder.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}Download the invoice as PDF
GET
/invoices/{invoice}/pdf
getInvoicePdf
The invoice in NONOX's own layout, as a PDF (a draft is marked as one). Counts toward the company's hourly PDF quota; above it 429.
Scope
Parameters
-
invoicestring (uuid) path requiredInvoice id (UUID, not the invoice number).
Responses
200 OK – The PDF.
application/pdfstring
401 Unauthorized – Missing, invalid, expired or revoked token or API key. Also returned when the person behind the credential has left the company (an OAuth grant is then revoked for good).
-
unauthenticatedNo valid credentialNyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.
403 Forbidden – The credential may not do this: a scope is missing, the granting person no longer has the permission, the address is not allowed, the company is archived (read-only) or no longer allows the app.
-
insufficient_scopeScope missing or permission lostNyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.
-
forbiddenThe action refuses (for example changing a posted voucher)Behörighet saknas för det här.
-
ip_not_allowedOutside the IP allowlistFöretaget tillåter inte anrop från den här adressen.
-
company_archivedWrite to an archived companyFöretaget är arkiverat och kan bara läsas.
-
app_not_allowedThe company no longer allows the appFöretaget tillåter inte längre den här appen.
404 Not Found – Not found. Also the answer for another company's ids (existence is never revealed) and for every call while NONOX Connect is turned off for the company.
-
not_foundUnknown id, other company's id, or module offDet du söker finns inte.
429 Too Many Requests – Rate limit exceeded (per credential, per company or per address). Wait Retry-After seconds.
-
rate_limitedOver the limitFör många anrop. Försök igen om 23 sekunder.
Code samples
curl "https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54/pdf" \
-H "Authorization: Bearer $NONOX_TOKEN" \
-H "Accept: application/json" \
-o kvitto.pdfuse Illuminate\Support\Facades\Http;
$response = Http::withToken(config('services.nonox.token'))
->acceptJson()
->get('https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54/pdf');
$response->throw();
file_put_contents('kvitto.pdf', $response->body());$client = new \GuzzleHttp\Client(['timeout' => 30]);
$response = $client->request('GET', 'https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54/pdf', [
'headers' => [
'Authorization' => 'Bearer '.getenv('NONOX_TOKEN'),
'Accept' => 'application/json',
],
'sink' => 'kvitto.pdf',
]);const response = await fetch('https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54/pdf', {
headers: {
Authorization: `Bearer ${process.env.NONOX_TOKEN}`,
Accept: 'application/json',
},
});
if (!response.ok) {
const problem = await response.json();
throw new Error(`${problem.code}: ${problem.detail}`);
}
const file = Buffer.from(await response.arrayBuffer());import os
import requests
response = requests.get(
"https://nonox.app/api/v1/invoices/5c2e8a41-7b3d-4f19-a6c2-0e9d8b7a6f54/pdf",
headers={
"Authorization": f"Bearer {os.environ['NONOX_TOKEN']}",
"Accept": "application/json",
},
timeout=30,
)
response.raise_for_status()
with open("kvitto.pdf", "wb") as file:
file.write(response.content)Error
4011 example
{
"type": "urn:nonox:problem:unauthenticated",
"title": "Unauthorized",
"status": 401,
"code": "unauthenticated",
"detail": "Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4035 examples
{
"type": "urn:nonox:problem:insufficient_scope",
"title": "Forbidden",
"status": 403,
"code": "insufficient_scope",
"detail": "Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
"required_scopes": [
"vouchers:post"
]
}{
"type": "urn:nonox:problem:forbidden",
"title": "Forbidden",
"status": 403,
"code": "forbidden",
"detail": "Behörighet saknas för det här.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:ip_not_allowed",
"title": "Forbidden",
"status": 403,
"code": "ip_not_allowed",
"detail": "Företaget tillåter inte anrop från den här adressen.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:company_archived",
"title": "Forbidden",
"status": 403,
"code": "company_archived",
"detail": "Företaget är arkiverat och kan bara läsas.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}{
"type": "urn:nonox:problem:app_not_allowed",
"title": "Forbidden",
"status": 403,
"code": "app_not_allowed",
"detail": "Företaget tillåter inte längre den här appen.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4041 example
{
"type": "urn:nonox:problem:not_found",
"title": "Not Found",
"status": 404,
"code": "not_found",
"detail": "Det du söker finns inte.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}4291 example
{
"type": "urn:nonox:problem:rate_limited",
"title": "Too Many Requests",
"status": 429,
"code": "rate_limited",
"detail": "För många anrop. Försök igen om 23 sekunder.",
"instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}