Partner Verification
Verify that your trading partners are legitimate and can receive Peppol documents.
Why Verify Partners?
Before sending invoices to a new trading partner, verify:
- Identity — Is this the right company?
- Registration — Are they on the Peppol network?
- Capabilities — Can they receive your document type?
- Access Point — Is their AP active and trusted?
Quick Verification
import requests
def verify_partner(scheme: str, identifier: str) -> dict:
"""Verify a trading partner."""
response = requests.get(
"https://app.goroute.ai/peppol-api/api/v1/partners/verify",
params={
"scheme": scheme,
"identifier": identifier
},
headers={"X-API-Key": "your_api_key"}
)
return response.json()
# Verify a partner
result = verify_partner("0106", "12345678")
if result["verified"]:
print(f"✅ Partner verified: {result['name']}")
print(f" Can receive: {', '.join(result['document_types'])}")
else:
print(f"❌ Verification failed: {result['reason']}")
Verification Response
{
"verified": true,
"partner": {
"scheme": "0106",
"identifier": "12345678",
"name": "Partner Company BV",
"country": "NL",
"verified_at": "2024-01-15T10:30:00Z"
},
"peppol_status": {
"registered": true,
"registration_date": "2023-06-15",
"access_point": {
"name": "Storecove",
"peppol_id": "POP000123",
"status": "active"
}
},
"capabilities": {
"can_receive_invoice": true,
"can_receive_credit_note": true,
"can_receive_order": false,
"supported_document_types": [
"Invoice",
"CreditNote"
]
},
"trust_indicators": {
"verified_identity": true,
"active_on_peppol": true,
"recent_activity": true,
"trust_score": 95
},
"checks_performed": [
{"check": "smp_lookup", "passed": true},
{"check": "identifier_validation", "passed": true},
{"check": "ap_status", "passed": true}
]
}
Verification Checks
| Check | Description |
|---|---|
| SMP Lookup | Partner is registered in Peppol SMP |
| Identifier Validation | Peppol ID format is valid |
| AP Status | Access Point is active and reachable |
| Certificate Validity | AP certificate is valid |
| Recent Activity | Partner has recent transactions |
Verification Levels
Level 1: Basic Lookup
Check if participant exists on Peppol:
result = verify_partner(
scheme="0106",
identifier="12345678"
)
# Returns: registered true/false
Level 2: Full Verification
Deep verification including business registry checks:
result = requests.get(
"https://app.goroute.ai/peppol-api/api/v1/partners/verify",
params={
"scheme": "0106",
"identifier": "12345678",
"level": "full"
},
headers={"X-API-Key": "your_api_key"}
)
# Includes: Business registry validation, trade register check
Level 3: Extended Due Diligence
For high-value or sensitive transactions:
result = requests.get(
"https://app.goroute.ai/peppol-api/api/v1/partners/verify",
params={
"scheme": "0106",
"identifier": "12345678",
"level": "extended"
},
headers={"X-API-Key": "your_api_key"}
)
# Includes: Credit check, sanctions screening
Batch Verification
Verify multiple partners at once:
def batch_verify(partners: list[dict]) -> dict:
"""Verify multiple partners in one request."""
response = requests.post(
"https://app.goroute.ai/peppol-api/api/v1/partners/verify/batch",
headers={
"X-API-Key": "your_api_key",
"Content-Type": "application/json"
},
json={"partners": partners}
)
return response.json()
# Verify your customer list
results = batch_verify([
{"scheme": "0106", "identifier": "12345678"},
{"scheme": "0106", "identifier": "87654321"},
{"scheme": "0208", "identifier": "0123456789"}
])
for result in results["results"]:
status = "✅" if result["verified"] else "❌"
print(f"{status} {result['scheme']}:{result['identifier']}: {result['reason']}")
Integration Patterns
Pre-Send Verification
Verify before every send:
class SecureSender:
def send_invoice(self, invoice_xml: str) -> dict:
# Extract receiver
receiver = self.extract_receiver(invoice_xml)
# Verify partner
verification = verify_partner(receiver["scheme"], receiver["identifier"])
if not verification["verified"]:
raise ValueError(f"Partner not verified: {verification['reason']}")
if not verification["capabilities"]["can_receive_invoice"]:
raise ValueError("Partner cannot receive invoices")
# Proceed with sending
return self.do_send(invoice_xml)
Onboarding Verification
Verify new trading partners during onboarding:
async def onboard_partner(partner_data: dict) -> dict:
"""Onboard a new trading partner with verification."""
# Verify on Peppol
verification = verify_partner(
partner_data["peppol_scheme"],
partner_data["peppol_id"]
)
if not verification["verified"]:
return {
"status": "manual_review",
"reason": verification["reason"],
"message": "Partner requires manual verification"
}
# Create partner record
partner = await create_partner(
**partner_data,
verified=True,
verification_date=datetime.utcnow()
)
return {"status": "active", "partner_id": partner.id}
Periodic Re-verification
Re-verify partners periodically:
from datetime import datetime, timedelta
async def reverify_partners():
"""Re-verify partners who haven't been verified recently."""
stale_threshold = datetime.utcnow() - timedelta(days=30)
partners = await db.query(
"SELECT * FROM partners WHERE last_verified < $1",
stale_threshold
)
for partner in partners:
verification = verify_partner(partner.scheme, partner.identifier)
await db.execute(
"""UPDATE partners
SET verified = $1,
last_verified = $2,
verification_data = $3
WHERE id = $4""",
verification["verified"],
datetime.utcnow(),
json.dumps(verification),
partner.id
)
if not verification["verified"]:
await notify_admin(f"Partner {partner.name} failed re-verification")
Verification Webhook
Get notified of partner status changes:
# Register for partner status webhooks
response = requests.post(
"https://app.goroute.ai/peppol-api/api/v1/webhooks",
headers={"X-API-Key": "your_api_key"},
json={
"url": "https://your-app.com/webhooks/peppol",
"events": ["partner.status_changed"]
}
)
# Webhook payload
{
"type": "partner.status_changed",
"data": {
"scheme": "0106",
"identifier": "12345678",
"previous_status": "active",
"new_status": "deregistered",
"reason": "Participant removed from SMP",
"detected_at": "2024-01-15T10:30:00Z"
}
}
Trust Score
GoRoute calculates a trust score based on:
| Factor | Weight | Description |
|---|---|---|
| Peppol Registration | 30% | Active SMP registration |
| Registration Age | 15% | Longer = more trusted |
| Transaction History | 25% | Successful document exchanges |
| AP Reputation | 15% | Access Point reliability |
| Identifier Validity | 15% | Valid business registry number |
# Get detailed trust score
result = verify_partner("0106", "12345678")
trust = result["trust_indicators"]
print(f"Trust Score: {trust['trust_score']}/100")
if trust["trust_score"] >= 80:
print("High trust - automatic processing")
elif trust["trust_score"] >= 50:
print("Medium trust - standard review")
else:
print("Low trust - manual verification required")