Skip to main content

Organizations & Multi-Tenancy

GoRoute is built for platforms that serve multiple businesses. Each business operates within its own organization, with complete data isolation.

What is an Organization?โ€‹

An organization represents a single business entity in GoRoute. Each organization has:

  • A unique identifier (org_id)
  • Its own Peppol participant registration(s)
  • Isolated invoice and transaction data
  • Separate webhook configurations
  • Independent rate limits

Multi-Tenant Architectureโ€‹

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Your Platform โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Customer A โ”‚ Customer B โ”‚ Customer C โ”‚
โ”‚ (org_001) โ”‚ (org_002) โ”‚ (org_003) โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚ โ”‚ โ”‚
โ–ผ โ–ผ โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ GoRoute API โ”‚
โ”‚ Complete data isolation per org_id โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚ โ”‚ โ”‚
โ–ผ โ–ผ โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Peppol Network โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Creating an Organizationโ€‹

curl -X POST https://app.goroute.ai/peppol-api/api/v1/organizations \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme Corporation",
"legal_name": "Acme Corporation B.V.",
"country": "NL",
"vat_number": "NL123456789B01",
"address": {
"street": "123 Business Street",
"city": "Amsterdam",
"postal_code": "1012 AB",
"country": "NL"
},
"contact": {
"email": "invoices@acme.example.com",
"phone": "+31201234567"
}
}'

Response:

{
"org_id": "org_abc123def456",
"name": "Acme Corporation",
"legal_name": "Acme Corporation B.V.",
"country": "NL",
"status": "active",
"created_at": "2026-01-26T10:00:00Z"
}

Organization Scopingโ€‹

All API operations are scoped to an organization. There are two approaches:

Your API key is associated with a default organization:

# Uses the default org for your API key
curl -X GET https://app.goroute.ai/peppol-api/api/v1/invoices \
-H "X-API-Key: YOUR_API_KEY"

Approach 2: Explicitโ€‹

Specify the organization in the request:

# Explicitly specify org_id
curl -X GET https://app.goroute.ai/peppol-api/api/v1/organizations/org_abc123/invoices \
-H "X-API-Key: YOUR_API_KEY"

Or use the header:

curl -X GET https://app.goroute.ai/peppol-api/api/v1/invoices \
-H "X-API-Key: YOUR_API_KEY" \
-H "X-Organization-Id: org_abc123"

Data Isolationโ€‹

Each organization's data is completely isolated:

Data TypeIsolation
Invoicesโœ… Fully isolated
Transactionsโœ… Fully isolated
Participantsโœ… Fully isolated
Webhooksโœ… Fully isolated
API Keysโœ… Scoped per org
Rate Limitsโœ… Independent per org
Security Guarantee

There is no way to access another organization's data through the API. All queries automatically filter by org_id.

Organization Statusโ€‹

StatusDescription
pendingCreated, awaiting verification
activeFully operational
suspendedTemporarily disabled (e.g., billing issue)
closedPermanently closed

Managing Organizationsโ€‹

List Organizationsโ€‹

curl -X GET https://app.goroute.ai/peppol-api/api/v1/organizations \
-H "X-API-Key: YOUR_API_KEY"

Get Organization Detailsโ€‹

curl -X GET https://app.goroute.ai/peppol-api/api/v1/organizations/org_abc123 \
-H "X-API-Key: YOUR_API_KEY"

Update Organizationโ€‹

curl -X PATCH https://app.goroute.ai/peppol-api/api/v1/organizations/org_abc123 \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contact": {
"email": "newemail@acme.example.com"
}
}'

Platform Integration Patternโ€‹

For platforms serving multiple customers:

class GoRouteClient:
def __init__(self, api_key: str):
self.api_key = api_key
self.base_url = "https://app.goroute.ai/peppol-api"

def send_invoice(self, org_id: str, invoice_data: dict):
"""Send invoice for a specific organization."""
response = requests.post(
f"{self.base_url}/api/v1/invoices",
headers={
"X-API-Key": self.api_key,
"X-Organization-Id": org_id # Scope to specific org
},
json=invoice_data
)
return response.json()

def get_transactions(self, org_id: str):
"""Get transactions for a specific organization."""
response = requests.get(
f"{self.base_url}/api/v1/transactions",
headers={
"X-API-Key": self.api_key,
"X-Organization-Id": org_id
}
)
return response.json()

Webhooks per Organizationโ€‹

Each organization can have its own webhook configuration:

curl -X POST https://app.goroute.ai/peppol-api/api/v1/organizations/org_abc123/webhooks \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yourplatform.com/webhooks/org_abc123",
"events": ["invoice.delivered", "invoice.received"],
"secret": "whsec_..."
}'

Best Practicesโ€‹

  1. One org per business โ€” Create a separate organization for each customer
  2. Store org_id โ€” Map your internal customer ID to GoRoute org_id
  3. Validate ownership โ€” Ensure users can only access their own organization
  4. Separate webhooks โ€” Configure unique webhook endpoints per organization

Next Stepsโ€‹