Client Libraries
There is no official GoRoute SDK for Python, Node.js, C#, Java or any other language. Nothing is available to install from PyPI, npm, NuGet or Maven Central.
Earlier revisions of this page listed four "official" SDKs with installation commands, quick-start code and repository links. None of those packages has ever been published, and none of those repositories exists. Code written against them has never worked.
If you copied an install command from this pageโ
Until this revision, this page printed package names for PyPI, npm, NuGet and Maven Central that GoRoute does not own or control, and linked to source repositories that return 404.
Please treat that as a supply-chain matter rather than a typo:
- Those names are unregistered. An unregistered name in a published install instruction is a dependency-confusion opportunity โ today the install simply fails, but whoever registers the name first can have their code run inside your build.
- Remove them from your dependency manifests (
requirements.txt,pyproject.toml,package.json,.csproj,pom.xml,build.gradle) and from any lockfile, then re-resolve. - If one of those names ever does resolve for you, do not trust it. It is not ours.
The names are deliberately not repeated on this page, so that they cannot be copied out of it again. To find what to remove, look for a dependency naming GoRoute or Peppol that you cannot trace back to a first-party source.
What to use insteadโ
The GoRoute Peppol API is plain HTTPS + JSON. There is no SDK to learn: authentication
is a single header, and sending a document is one POST with a JSON body. A working client
is a few lines in any language that can make an HTTP request.
The one endpoint most integrations needโ
| Method and path | POST /api/v1/documents |
| Base URL | https://app.goroute.ai/peppol-api |
| Full URL | https://app.goroute.ai/peppol-api/api/v1/documents |
| Auth header | X-API-Key: your_api_key |
| Content type | application/json |
| Optional header | Idempotency-Key โ prevents duplicate sends on retry |
| Success status | 202 Accepted (queued for asynchronous delivery) |
Request body:
| Field | Required | Notes |
|---|---|---|
receiver_scheme | Yes | Receiver Peppol scheme, e.g. 9959 |
receiver_id | Yes | Receiver Peppol identifier |
document | Yes | The UBL document as an XML string inside the JSON body โ you do not POST raw XML |
sender_scheme | No | Defaults to your organization's participant |
sender_id | No | Defaults to your organization's participant |
metadata | No | Free-form object stored with the transaction |
A successful response returns transaction_id, status and created_at. Track delivery
with webhooks or by polling the transaction.
For the complete send workflow, including the UBL document itself, see Sending an Invoice.
Pythonโ
Using requests:
import requests
with open("invoice.xml", "r", encoding="utf-8") as f:
invoice_xml = f.read()
response = requests.post(
"https://app.goroute.ai/peppol-api/api/v1/documents",
headers={
"X-API-Key": "your_api_key",
"Content-Type": "application/json",
# Optional: makes the send safe to retry
"Idempotency-Key": "invoice-2026-00123",
},
json={
"receiver_scheme": "9959",
"receiver_id": "987654321",
"document": invoice_xml,
},
timeout=30,
)
response.raise_for_status() # 202 on success
result = response.json()
print(result["transaction_id"], result["status"])
For async applications the same call with httpx.AsyncClient or aiohttp works
identically โ there is nothing GoRoute-specific about it.
Node.js / TypeScriptโ
Using the built-in fetch (Node 18+):
import { readFile } from 'node:fs/promises';
const invoiceXml = await readFile('invoice.xml', 'utf8');
const response = await fetch(
'https://app.goroute.ai/peppol-api/api/v1/documents',
{
method: 'POST',
headers: {
'X-API-Key': process.env.GOROUTE_API_KEY,
'Content-Type': 'application/json',
// Optional: makes the send safe to retry
'Idempotency-Key': 'invoice-2026-00123',
},
body: JSON.stringify({
receiver_scheme: '9959',
receiver_id: '987654321',
document: invoiceXml,
}),
},
);
if (!response.ok) {
throw new Error(`Send failed: ${response.status} ${await response.text()}`);
}
const result = await response.json(); // 202 Accepted
console.log(result.transaction_id, result.status);
C# / .NETโ
Using HttpClient:
using System.Net.Http;
using System.Net.Http.Json;
using System.Text.Json;
var invoiceXml = await File.ReadAllTextAsync("invoice.xml");
using var http = new HttpClient
{
BaseAddress = new Uri("https://app.goroute.ai/peppol-api/")
};
http.DefaultRequestHeaders.Add(
"X-API-Key", Environment.GetEnvironmentVariable("GOROUTE_API_KEY"));
using var request = new HttpRequestMessage(HttpMethod.Post, "api/v1/documents")
{
Content = JsonContent.Create(new
{
receiver_scheme = "9959",
receiver_id = "987654321",
document = invoiceXml
})
};
// Optional: makes the send safe to retry
request.Headers.Add("Idempotency-Key", "invoice-2026-00123");
var response = await http.SendAsync(request);
response.EnsureSuccessStatusCode(); // 202 on success
using var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
Console.WriteLine(payload.RootElement.GetProperty("transaction_id").GetString());
Register the HttpClient with IHttpClientFactory and add your own Polly retry policy in
the usual way โ none of that is GoRoute-specific.
Javaโ
Using java.net.http.HttpClient (Java 11+):
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;
String invoiceXml = Files.readString(Path.of("invoice.xml"));
String body = new ObjectMapper().writeValueAsString(Map.of(
"receiver_scheme", "9959",
"receiver_id", "987654321",
"document", invoiceXml
));
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://app.goroute.ai/peppol-api/api/v1/documents"))
.header("X-API-Key", System.getenv("GOROUTE_API_KEY"))
.header("Content-Type", "application/json")
// Optional: makes the send safe to retry
.header("Idempotency-Key", "invoice-2026-00123")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode()); // 202 on success
System.out.println(response.body());
Generating a client from the OpenAPI documentโ
You can point OpenAPI Generator or a similar tool at our published specification โ see the Code Generation guide.
The published OpenAPI document describes 8 paths. The live API exposes several hundred. A client generated from it will therefore cover a small fraction of the product, and the absence of a method in a generated client tells you nothing about whether the endpoint exists.
Generate a client for the endpoints the specification actually contains, and write the rest by hand against this documentation.
Webhooksโ
Webhook payloads are not covered on this page. Earlier revisions carried a webhook handler sample here that used the wrong envelope field and two event names that do not exist in the product.
The canonical references are:
- Webhook reference โ payload envelope, event catalogue and signature verification
- Webhook setup โ registering and testing an endpoint
Getting Helpโ
- ๐ง Email: admin@goroute.ai
- ๐ Sending an Invoice โ the full send workflow
- ๐ Authentication โ obtaining and managing API keys
- ๐งช Postman collection โ explore the API interactively