Skip to main content

Support & Resources

Get help with your GoRoute integration.

Getting Helpโ€‹

Support Channelsโ€‹

ChannelContactUse For
๐Ÿ“ง Support emailsupport@goroute.aiAll severities โ€” the main way in
๐Ÿšจ Engineering escalationengineering@goroute.aiP1 and P2 escalation only
๐Ÿ–ฅ๏ธ Dashboardapp.goroute.aiRaise and track tickets, read API docs
๐Ÿ”ง Support ticket APIPOST /api/v1/ticketsRaise and track tickets from your own system โ€” see Support Tickets API
๐Ÿ“– DocumentationThis siteSelf-service

Response times depend on the severity of the issue, not on the channel you use. See Response Times.

Support Hoursโ€‹

CoverHours
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.

LevelWhoTriggerContact
L1Support engineerYour initial contactsupport@goroute.ai
L2Senior engineerL1 cannot resolve within 2 hoursengineering@goroute.ai
L3Engineering leadA P1 is unresolved after 4 hoursWe notify you directly
ExecutiveCTO / CEOA P1 is unresolved after 8 hoursWe 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:

  1. API Request ID โ€” Found in response headers (X-Request-ID)
  2. Transaction ID โ€” For specific transaction issues
  3. Timestamp โ€” When the issue occurred (UTC preferred)
  4. Request/Response โ€” Sanitized copies (remove API keys)
  5. 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:

FieldTypeNotes
subjectstring1-255 characters
descriptionstringAt least 1 character. Put the detail from Gather This Information here.

Optional:

FieldTypeNotes
severitystringP1, P2, P3 or P4. This is a request, not a setting โ€” triage may revise it. Leave it out and triage assigns one.
categorystringThe topic. See the list below. An unrecognised value is rejected.
subcategorystringFree text, up to 80 characters
channel_contextstringWhich part of the product: portal, bulk, connector, api or unknown. An unrecognised value is rejected.
connector_namestringYour ERP's name when channel_context is connector โ€” for example Odoo, SAP, Xero
related_txn_idUUIDThe Peppol transaction this ticket is about. Mandatory for some topics โ€” see below.
tagsarray of stringsYour own labels
requester_emailstringWho to reply to, if not the signed-in user
requester_namestring

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.

ValueTopic
sendingSending invoices (outbound)
receivingReceiving invoices (inbound)
deliveryDelivery issues
validationValidation and compliance
bulk_importBulk upload / import
connectorConnector / ERP integration
apiAPI / developer
onboardingOnboarding and registration
billingAccount, billing and plans
whitelabelWhite-label / partner management (for white-label partners)
otherOther / general
A transaction topic needs the transaction ID

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:

FieldWhat it is
requester_typeHow 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_labelThe same, in words, for example "Direct GoRoute customer"
partner_nameThe partner's brand name when requester_type is partner_client. null otherwise.
channelsThe values channel_context accepts, as a list of key and label
topicsThe 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.
subcategoriesSuggested subcategory values, keyed by topic. They are suggestions: subcategory itself is free text.
erpsSuggested connector_name values
txn_required_topicsThe 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.

ParameterTypeNotes
pageintegerDefaults to 1
page_sizeinteger1-100, defaults to 50
statusstringFilter by status: new, ai_triage, open, pending, on_hold, escalated, resolved, closed, reopened
severitystringFilter by severity: P1 to P4
open_onlybooleanDefaults 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.

Why you may see fewer tickets than you expect

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:

FieldWhat it is
descriptionThe full text you sent when you raised the ticket. The list leaves this out.
commentsThe conversation, oldest first. Each entry carries author_name, author_kind, body, visibility, is_system and created_at.
eventsThe timeline โ€” each change of status, severity, assignee and so on, as event_type with from_value and to_value.
attachmentsFiles 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.
Two things about comments that look wrong and are not

Every 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.

A colleague's ticket answers 404, not 403

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

FieldTypeNotes
bodystringRequired. 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.

Your reply is always public

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.

Read status before you reopen

The 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:

FieldWhat it is
idThe attachment's id. You need it to download the file.
ticket_idThe ticket it belongs to.
comment_idnull. The file belongs to the ticket, not to a reply.
filenameThe file name as stored (see below).
content_typeThe file type you declared.
size_bytesThe size of the file.
created_atWhen 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:

StatusMessageWhy
400Empty fileThe file has no content.
413File too large (max 10 MB)The file is larger than 10 MB.
415Unsupported 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 q more 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:

FieldWhat it is
idThe article's id.
org_idYour organisation's id, or null for an article GoRoute publishes for everyone.
titleThe article's title.
bodyThe full text of the article.
categoryA category label, or null.
tagsA list of tags; empty when there are none.
statusAlways published here.
viewsA view count. See "Order" above.
created_at, updated_atWhen 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โ€‹

PlanMonthly Uptime
Starter99.5%
Professional99.9%
Enterprise99.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.

SeverityWhat it meansFirst responseStatus updatesResolution target
P1 โ€” CriticalComplete service outage, or a risk of data loss15 minutesEvery hour4 hours
P2 โ€” HighMajor feature unavailable with no workaround1 hourEvery 4 hours8 hours
P3 โ€” MediumFeature impaired, but a workaround exists4 hoursEvery 24 hours5 business days
P4 โ€” LowMinor issue, cosmetic, or an enhancement request1 business dayWeeklyBest 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

Schedule Onboarding โ†’

Technical Deep Diveโ€‹

For Enterprise customers:

  • Architecture review
  • Integration best practices
  • Performance optimization
  • Security review

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:

  1. Email support@goroute.ai, or raise a ticket with severity: "P1" through the Support Tickets API or the dashboard.
  2. 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