API
The Nori API is a GraphQL API – a single endpoint through which you request exactly the data you need and trigger the actions you want.
Our API is built on GraphQL. The central endpoint is https://api.noridocs.com/graphql. At api.noridocs.com we also provide an interactive playground. There you test queries and mutations right in the browser – with schema autocompletion and docs, without writing a line of code.
Authentication
Most fields require a bearer token in the Authorization header. The connectivity check noriPing works without a token – handy to verify the connection:
query {
noriPing
}
Example: Query
A query asks for exactly the fields you need. Here, the open invoices with their customer:
query {
noriInvoices(status: "open", first: 10) {
data {
id
number
title
status
customer { name }
}
paginatorInfo { total }
}
}
{
"data": {
"noriInvoices": {
"data": [
{
"id": "1024",
"number": "2025-0007",
"title": "Website Relaunch",
"status": "open",
"customer": { "name": "Acme Studio" }
}
],
"paginatorInfo": { "total": 1 }
}
}
}
Example: Mutation
A mutation creates or changes data – for example a new draft invoice:
mutation {
noriCreateInvoice(input: {
customer_id: "42"
title: "Website Relaunch"
currency: "EUR"
lines: [
{ title: "Design", quantity: 1, unit_price_cents: 250000 }
{ title: "Development", quantity: 1, unit_price_cents: 800000 }
]
}) {
id
number
status
}
}
{
"data": {
"noriCreateInvoice": {
"id": "1025",
"number": null,
"status": "draft"
}
}
}
Sending requests
GraphQL runs over a single POST request. You send JSON with a query field and optional variables. Here it is with cURL – once as a query, once as a mutation:
# Query: current user
curl https://api.noridocs.com/graphql \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"query":"query { me { id name email } }"}'
# Mutation: create an invoice (with variables)
curl https://api.noridocs.com/graphql \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"query": "mutation ($input: NoriCreateInvoiceInput!) { noriCreateInvoice(input: $input) { id number status } }",
"variables": { "input": { "customer_id": "42", "lines": [{ "title": "Design", "quantity": 1, "unit_price_cents": 250000 }] } }
}'
In JavaScript, define a small helper once and reuse it everywhere:
// Define once – works for queries and mutations alike.
async function nori(query, variables = {}) {
const res = await fetch('https://api.noridocs.com/graphql', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.NORI_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ query, variables }),
});
const { data, errors } = await res.json();
if (errors) throw new Error(errors[0].message);
return data;
}
// Query
const { me } = await nori(`query { me { id name email } }`);
// Mutation
const { noriCreateInvoice } = await nori(
`mutation ($input: NoriCreateInvoiceInput!) {
noriCreateInvoice(input: $input) { id number status }
}`,
{ input: { customer_id: '42', lines: [{ title: 'Design', quantity: 1, unit_price_cents: 250000 }] } },
);
Get going fast with a client
For production, reach for a lightweight GraphQL client. graphql-request is tiny, handles variables, and turns queries and mutations into one-liners:
import { GraphQLClient, gql } from 'graphql-request';
const client = new GraphQLClient('https://api.noridocs.com/graphql', {
headers: { Authorization: `Bearer ${process.env.NORI_TOKEN}` },
});
// Query
const { me } = await client.request(gql`
query { me { id name email } }
`);
// Mutation
const { noriCreateInvoice } = await client.request(
gql`
mutation ($input: NoriCreateInvoiceInput!) {
noriCreateInvoice(input: $input) { id number status }
}
`,
{ input: { customer_id: '42', lines: [{ title: 'Design', quantity: 1, unit_price_cents: 250000 }] } },
);