Support & Resources
Get help with your GoRoute integration.
Getting Helpโ
Support Channelsโ
| Channel | Contact | Use For |
|---|---|---|
| ๐ง Support email | support@goroute.ai | All severities โ the main way in |
| ๐จ Engineering escalation | engineering@goroute.ai | P1 and P2 escalation only |
| ๐ฅ๏ธ Dashboard | app.goroute.ai | Raise and track tickets, read API docs |
| ๐ง Support ticket API | POST /api/v1/tickets | Raise and track tickets from your own system โ see Support Tickets API |
| ๐ Documentation | This site | Self-service |
Response times depend on the severity of the issue, not on the channel you use. See Response Times.
Support Hoursโ
| Cover | Hours |
|---|---|
| P1 and P2 (critical and high) | 24/7/365 |
| P3 and P4 (medium and low) | Monday - Friday, 08:00-18:00 US Eastern (America/New_York) |
Escalation Pathโ
If an issue is not moving, you can escalate it. Each level below is reached either by asking us to escalate or automatically, at the trigger shown.
| Level | Who | Trigger | Contact |
|---|---|---|---|
| L1 | Support engineer | Your initial contact | support@goroute.ai |
| L2 | Senior engineer | L1 cannot resolve within 2 hours | engineering@goroute.ai |
| L3 | Engineering lead | A P1 is unresolved after 4 hours | We notify you directly |
| Executive | CTO / CEO | A P1 is unresolved after 8 hours | We notify you directly |
Separately from your own escalation, a service outage lasting more than four hours or a security incident is reported by us to the Peppol Authority, as the Peppol Transport Policy requires.
Before Contacting Supportโ
Gather This Informationโ
For faster resolution, please provide:
- API Request ID โ Found in response headers (
X-Request-ID) - Transaction ID โ For specific transaction issues
- Timestamp โ When the issue occurred (UTC preferred)
- Request/Response โ Sanitized copies (remove API keys)
- Error Messages โ Complete error response
Example Support Requestโ
Subject: Transaction delivery failure - tx_abc123
Issue: Invoice not delivered after 2 hours
Details:
- Transaction ID: tx_abc123
- Request ID: req_xyz789
- Receiver: 0192:987654321
- Error: TX_005 - Delivery failed
- Timestamp: 2024-01-15T10:30:00Z
Steps to reproduce:
1. POST /api/v1/documents with attached invoice
2. Transaction created successfully
3. Status stuck on "sending" for 2+ hours
Expected: Delivery within 15 minutes
Actual: Still pending after 2 hours
Attachments:
- Invoice XML (sanitized)
- API response
Support Tickets APIโ
You do not have to use email. GoRoute has a support-ticket API, so you can raise a ticket and follow it from your own system โ a helpdesk, a monitoring alert, or your own application.
Tickets live under https://app.goroute.ai/peppol-api/api/v1/tickets. Authenticate with
your API key in the X-API-Key header, exactly as for the rest of the API. Every request
is scoped to your own organisation; you cannot see another organisation's tickets.
Create a Ticketโ
POST /api/v1/tickets โ 201 Created
Required:
| Field | Type | Notes |
|---|---|---|
subject | string | 1-255 characters |
description | string | At least 1 character. Put the detail from Gather This Information here. |
Optional:
| Field | Type | Notes |
|---|---|---|
severity | string | P1, P2, P3 or P4. This is a request, not a setting โ triage may revise it. Leave it out and triage assigns one. |
category | string | The topic. See the list below. An unrecognised value is rejected. |
subcategory | string | Free text, up to 80 characters |
channel_context | string | Which part of the product: portal, bulk, connector, api or unknown. An unrecognised value is rejected. |
connector_name | string | Your ERP's name when channel_context is connector โ for example Odoo, SAP, Xero |
related_txn_id | UUID | The Peppol transaction this ticket is about. Mandatory for some topics โ see below. |
tags | array of strings | Your own labels |
requester_email | string | Who to reply to, if not the signed-in user |
requester_name | string |
Valid category values are below. This table is our copy, kept here so the page reads on
its own. The authoritative list for your organisation comes from
Topic and Channel Lists: read it from there if your code builds
a form or checks a value. The whitelabel topic is offered only to white-label partners.
| Value | Topic |
|---|---|
sending | Sending invoices (outbound) |
receiving | Receiving invoices (inbound) |
delivery | Delivery issues |
validation | Validation and compliance |
bulk_import | Bulk upload / import |
connector | Connector / ERP integration |
api | API / developer |
onboarding | Onboarding and registration |
billing | Account, billing and plans |
whitelabel | White-label / partner management (for white-label partners) |
other | Other / general |
If category is sending, receiving, delivery or validation, you must also send
related_txn_id. Without it the request is refused โ that transaction is what support
needs in order to investigate anything. Tickets with no category at all are not subject
to this rule.
curl -X POST https://app.goroute.ai/peppol-api/api/v1/tickets \
-H "X-API-Key: your_key" \
-H "Content-Type: application/json" \
-d '{
"subject": "Invoice rejected by recipient AP",
"description": "Transaction failed with a Schematron error. What does BR-CO-10 mean?",
"category": "validation",
"severity": "P3",
"channel_context": "api",
"related_txn_id": "550e8400-e29b-41d4-a716-446655440000",
"tags": ["validation", "bis3"]
}'
The response is the full ticket, including its conversation so far and any attachments. Internal notes written by our agents are never included.
Topic and Channel Listsโ
GET /api/v1/tickets/form-config โ 200 OK
This call returns the lists a ticket form is built from: the topics, the product channels, the suggested sub-categories, the ERP names, and which topics need a transaction ID. Read it instead of copying the tables on this page, so your form follows the product when a list changes.
No permission beyond authenticating as your organisation is required.
curl "https://app.goroute.ai/peppol-api/api/v1/tickets/form-config" \
-H "X-API-Key: your_key"
The published API description gives this response no schema. The fields below are read from the service's source code:
| Field | What it is |
|---|---|
requester_type | How GoRoute sees your organisation: direct (a GoRoute customer), partner (a white-label partner) or partner_client (a client of a white-label partner) |
requester_type_label | The same, in words, for example "Direct GoRoute customer" |
partner_name | The partner's brand name when requester_type is partner_client. null otherwise. |
channels | The values channel_context accepts, as a list of key and label |
topics | The values category accepts, as a list of key, label and triage. triage is the internal group our support team files the topic under; you do not send it. |
subcategories | Suggested subcategory values, keyed by topic. They are suggestions: subcategory itself is free text. |
erps | Suggested connector_name values |
txn_required_topics | The topics for which related_txn_id is mandatory |
The topics list depends on who is asking. The whitelabel topic is in it only when
requester_type is partner. Everyone else gets the list without it.
List Your Ticketsโ
GET /api/v1/tickets โ a paginated list.
| Parameter | Type | Notes |
|---|---|---|
page | integer | Defaults to 1 |
page_size | integer | 1-100, defaults to 50 |
status | string | Filter by status: new, ai_triage, open, pending, on_hold, escalated, resolved, closed, reopened |
severity | string | Filter by severity: P1 to P4 |
open_only | boolean | Defaults to false. When true, excludes resolved and closed tickets. |
curl "https://app.goroute.ai/peppol-api/api/v1/tickets?open_only=true&severity=P1" \
-H "X-API-Key: your_key"
This endpoint needs the tickets:read permission.
A signed-in dashboard user who is not an owner or admin of your organisation sees only the tickets they opened themselves. Owners, admins, and callers using an API key see every ticket in the organisation. A short list is a permission scope, not missing data.
Read One Ticketโ
GET /api/v1/tickets/{ticket_id} โ the ticket, plus the whole conversation.
This endpoint needs the tickets:read permission.
curl "https://app.goroute.ai/peppol-api/api/v1/tickets/550e8400-e29b-41d4-a716-446655440000" \
-H "X-API-Key: your_key"
You get every field the list gives you, plus four more:
| Field | What it is |
|---|---|
description | The full text you sent when you raised the ticket. The list leaves this out. |
comments | The conversation, oldest first. Each entry carries author_name, author_kind, body, visibility, is_system and created_at. |
events | The timeline โ each change of status, severity, assignee and so on, as event_type with from_value and to_value. |
attachments | Files on the ticket: id, filename, content_type, size_bytes and created_at. Each also has a comment_id, which is null: the service attaches a file to the ticket, not to a reply. Attach a file adds one; Download an Attachment fetches one. |
comments that look wrong and are notEvery reply from our side appears under one name. You will not see which engineer answered, or whether the answer came from first-line or second-line support, or โ if you reached us through a partner who resells GoRoute โ whether it was the partner's desk or ours. Agent replies are deliberately shown under a single name so the conversation reads as one. A thread that looks like it had a single author usually did not.
Internal notes are never in the list. Our agents write notes to each other on a ticket.
Those are filtered out before the response is built, so comments is the conversation you
are part of, not the complete record. visibility on every comment you can see is therefore
always public.
If you are a signed-in dashboard user who is not an owner or admin, you can only open
tickets you raised. Asking for one a colleague in your own organisation raised returns
404 Not Found with error_code: "TICKET_NOT_FOUND" โ not 403 Forbidden.
This is deliberate. A 403 would confirm that the ticket exists, so the API declines to distinguish "this ticket is not yours" from "there is no such ticket". Do not report it as a bug, and do not retry it. Ask an owner or admin, or use an API key, which sees every ticket in the organisation.
Reply to a Ticketโ
POST /api/v1/tickets/{ticket_id}/comments โ 201 Created
| Field | Type | Notes |
|---|---|---|
body | string | Required. At least one character. |
curl -X POST \
"https://app.goroute.ai/peppol-api/api/v1/tickets/550e8400-e29b-41d4-a716-446655440000/comments" \
-H "X-API-Key: your_key" \
-H "Content-Type: application/json" \
-d '{"body": "Re-sent the invoice this morning and it delivered. Please close."}'
The response is the one comment that was created, not the whole ticket. Fetch the ticket again if you want the updated conversation.
No permission beyond authenticating as your organisation is required to reply. The 404-not-403 rule above applies here too: replying to a ticket you cannot see answers 404.
A reply you post is always a public, customer-authored comment. The tenant-facing API does
not write internal agent notes, and nothing you send can make it write one. If you are
reading the generated API Reference and see a visibility field on
this request body offering internal, ignore it: on this route the value is not used.
Anything you write here can be read by anyone in your organisation who can see the ticket.
Reopen a Ticketโ
POST /api/v1/tickets/{ticket_id}/reopen โ 200 OK
Use this when a ticket was resolved or closed and the problem has come back. The ticket
moves to reopened and our support team sees it again. There is no request body.
curl -X POST \
"https://app.goroute.ai/peppol-api/api/v1/tickets/550e8400-e29b-41d4-a716-446655440000/reopen" \
-H "X-API-Key: your_key"
The response is the full ticket, in the same shape as Read One Ticket.
The change is recorded on the ticket's timeline as a status_changed event, from the old
status to reopened.
No permission beyond authenticating as your organisation is required. The 404-not-403 rule above applies here too: reopening a ticket you cannot see answers 404.
status before you reopenThe service does not currently refuse this call on a ticket that is still open. A ticket
in any status other than reopened is moved to reopened, including one our team is
working on or one that is waiting for your reply (pending). Reopening a pending ticket
also starts the clock on how long support has to resolve it running again. That clock is
paused while a ticket waits for you, and it carries on from where it stopped; it does not
start from zero. Calling it on a ticket that
is already reopened changes nothing.
So check status first, and reopen only a resolved or closed ticket. To add
information to a ticket that is still open, reply to it instead.
Attach a Fileโ
POST /api/v1/tickets/{ticket_id}/attachments โ 201 Created
Use this to add a screenshot, a log, an invoice file or a spreadsheet to a ticket. Send the
file as multipart/form-data, in a field named file. One file per call.
curl -X POST \
"https://app.goroute.ai/peppol-api/api/v1/tickets/550e8400-e29b-41d4-a716-446655440000/attachments" \
-H "X-API-Key: your_key" \
-F "file=@rejected-invoice.xml;type=application/xml"
The response is the attachment that was stored:
| Field | What it is |
|---|---|
id | The attachment's id. You need it to download the file. |
ticket_id | The ticket it belongs to. |
comment_id | null. The file belongs to the ticket, not to a reply. |
filename | The file name as stored (see below). |
content_type | The file type you declared. |
size_bytes | The size of the file. |
created_at | When it was stored. |
The file then appears in the ticket's attachments list when you
read the ticket.
File types. The type is the one you declare for the file part. These are accepted:
- images:
image/png,image/jpeg,image/gif,image/webp; - documents:
application/pdf,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document; - spreadsheets:
application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,text/csv; - text and data:
text/plain,text/xml,application/xml,application/json; - archives and anything else:
application/zip,application/octet-stream.
A part with no declared type counts as application/octet-stream, so it is accepted. The
type is compared exactly as you send it, so declare it without extras such as
; charset=utf-8. Setting type= in curl -F, as in the example, makes it explicit.
File names. Any folder path in the name is dropped. Any character other than a letter, a
digit, a space or ._()- is replaced with _, and the name is cut to 120 characters.
No permission beyond authenticating as your organisation is required to attach a file. The
404-not-403 rule above applies here too: attaching to a ticket you cannot see answers 404
with error_code: "TICKET_NOT_FOUND".
Refusals:
| Status | Message | Why |
|---|---|---|
400 | Empty file | The file has no content. |
413 | File too large (max 10 MB) | The file is larger than 10 MB. |
415 | Unsupported file type: โฆ | The declared type is not in the list above. The message names the type you sent. |
These come back as {"error": "error", "message": "โฆ", "request_id": "โฆ"}.
Download an Attachmentโ
GET /api/v1/tickets/{ticket_id}/attachments/{attachment_id} โ the file
attachment_id is the id from the upload response, or from the ticket's attachments
list. This endpoint needs the tickets:read permission.
curl "https://app.goroute.ai/peppol-api/api/v1/tickets/550e8400-e29b-41d4-a716-446655440000/attachments/ATTACHMENT_ID" \
-H "X-API-Key: your_key" \
-o rejected-invoice.xml
The response body is the file itself, not JSON. Its Content-Type is the type stored with
it, and Content-Disposition: attachment carries the stored file name.
The 404-not-403 rule above applies: a ticket you cannot see answers 404 with
error_code: "TICKET_NOT_FOUND". An attachment id that does not belong to that ticket
answers 404 with error_code: "ATTACHMENT_NOT_FOUND".
Search Help Articlesโ
GET /api/v1/tickets/kb/search โ 200 OK
Use this to find a published help article before you open a ticket. This endpoint needs the
tickets:read permission.
curl -G "https://app.goroute.ai/peppol-api/api/v1/tickets/kb/search" \
-H "X-API-Key: your_key" \
--data-urlencode "q=credit note"
The search text. q is optional. It matches anywhere in an article's title or body, and
capitalisation is ignored. Only its first 80 characters are used. The characters % and _ in
q are not taken literally: % matches any run of text and _ matches any single character.
What you get back. A JSON list, not an object:
- only published articles โ drafts are never returned;
- your organisation's own articles, plus articles GoRoute publishes for everyone (those have
org_id: null); - at most 20 articles. There is no paging, so make
qmore specific if what you want is not among them; - with no
q, the first 20 published articles.
Order. Do not rely on it. The list is sorted by each article's views count, but nothing in
the service increases that count today, so it does not reflect how popular an article is.
Each article carries:
| Field | What it is |
|---|---|
id | The article's id. |
org_id | Your organisation's id, or null for an article GoRoute publishes for everyone. |
title | The article's title. |
body | The full text of the article. |
category | A category label, or null. |
tags | A list of tags; empty when there are none. |
status | Always published here. |
views | A view count. See "Order" above. |
created_at, updated_at | When the article was written and last changed. |
The Rest of the Ticket APIโ
One operation exists but is not written up on this page yet. It is in the generated API Reference with its full request and response:
POST /api/v1/tickets/{ticket_id}/csatโ rate your support experience, 1 to 5
Self-Service Resourcesโ
Dashboardโ
Access your dashboard at app.goroute.ai:
- View API usage and analytics
- Manage API keys
- Check transaction history
- Configure webhooks
Common Issuesโ
"Invalid API Key" (AUTH_001)โ
# 1. Confirm the service is reachable โ /health takes no API key
curl https://app.goroute.ai/peppol-api/health
# 2. Then exercise the key itself against an authenticated endpoint
curl -H "X-API-Key: your_key" \
https://app.goroute.ai/peppol-api/api/v1/participants
Solutions:
- Check for extra whitespace in key
- Ensure key hasn't been rotated
- Verify key has required scopes
"Participant Not Found" (PART_001)โ
# Check if participant is registered โ peppol_id is a single scheme:value string
response = requests.get(
"https://app.goroute.ai/peppol-api/api/v1/participants/lookup",
params={"peppol_id": "0192:123456789"},
headers={"X-API-Key": api_key}
)
Solutions:
- Verify identifier format
- Check recipient is registered on Peppol
- Try looking up on production SMP
"Validation Failed" (VAL_003)โ
# Get detailed validation errors โ the XML travels as a string in `document`
response = requests.post(
"https://app.goroute.ai/peppol-api/api/v1/documents/validate",
json={"document": invoice_xml},
headers={"X-API-Key": api_key, "Content-Type": "application/json"}
)
print(response.json()["issues"])
Solutions:
- Review Schematron rule in error message
- Check Error Codes for rule explanation
- Validate locally first
Rate Limiting (429)โ
# Check rate limit headers
response = requests.get(url, headers={"X-API-Key": api_key})
remaining = response.headers.get("X-RateLimit-Remaining")
reset = response.headers.get("X-RateLimit-Reset")
Solutions:
- Implement exponential backoff
- Batch requests where possible
- Contact us for rate limit increase
Service Level Agreementโ
API Availabilityโ
| Plan | Monthly Uptime |
|---|---|
| Starter | 99.5% |
| Professional | 99.9% |
| Enterprise | 99.99% |
Response Timesโ
Response and resolution targets are set by the severity of the issue, not by your plan. Severity is assigned when the ticket is triaged; you can request a severity when you raise a ticket, and triage may revise it.
| Severity | What it means | First response | Status updates | Resolution target |
|---|---|---|---|---|
| P1 โ Critical | Complete service outage, or a risk of data loss | 15 minutes | Every hour | 4 hours |
| P2 โ High | Major feature unavailable with no workaround | 1 hour | Every 4 hours | 8 hours |
| P3 โ Medium | Feature impaired, but a workaround exists | 4 hours | Every 24 hours | 5 business days |
| P4 โ Low | Minor issue, cosmetic, or an enhancement request | 1 business day | Weekly | Best effort |
How these clocks run:
- P1 and P2 run around the clock. The 15-minute and 1-hour first-response targets are wall-clock time, any hour of any day.
- P3 and P4 run during business hours only. A business day here means the 10-hour window Monday to Friday, 08:00-18:00 US Eastern. A ticket raised at 17:00 on a Friday has most of its P3 first-response window waiting on Monday morning.
- P1 escalates by itself after 2 hours, P2 after 6 hours, without you asking.
- The resolution clock pauses while a ticket is waiting on you and restarts when you reply, so time spent waiting for your information is not counted against the target.
- Your contract may set different figures. Response targets can be overridden for an individual organisation; where that has been agreed, the agreed figures apply instead of the ones above.
What's Coveredโ
- โ API endpoint availability
- โ Peppol network connectivity
- โ Document delivery
- โ Webhook delivery
What's Not Coveredโ
- โ Scheduled maintenance (announced 48h+ in advance)
- โ Recipient Access Point issues
- โ Client-side integration bugs
- โ Invalid document rejections
Training & Onboardingโ
Getting Started Sessionโ
Free 30-minute onboarding for all plans:
- API overview
- Authentication setup
- First invoice walkthrough
- Q&A
Technical Deep Diveโ
For Enterprise customers:
- Architecture review
- Integration best practices
- Performance optimization
- Security review
Useful Linksโ
Documentationโ
Toolsโ
External Resourcesโ
Feedbackโ
We value your feedback! Help us improve:
- ๐ก Feature Requests: support@goroute.ai, or raise a P4 ticket
- ๐ Documentation Issues: Click "Edit this page" on any doc
- โญ Reviews: Share your experience
Emergency Contactโ
Critical production problems are handled as P1, and P1 cover runs 24/7/365. There is no separate out-of-hours route โ use the normal channels and they will be picked up at any hour:
- Email support@goroute.ai, or raise a ticket with
severity: "P1"through the Support Tickets API or the dashboard. - If it has not moved within 2 hours, escalate to engineering@goroute.ai.
A P1 is a complete service outage or a risk of data loss. Examples:
- Our Access Point is unreachable on the Peppol network
- Our SMP is returning errors to the Peppol SML
- AS4 message delivery has halted
- A security breach or a compromised certificate
A P1 auto-escalates to a senior engineer after 2 hours, to the engineering lead after 4, and to the CTO or CEO after 8.
Email: support@goroute.ai Dashboard: app.goroute.ai