Skip to content
Deze documentatie wordt actief uitgebreid — kom regelmatig terug.

CTN Association Register - Format and Data Service Specification

Based on BDI Association Register Format and Data Service Documentation

This document specifies the data formats, API contracts, and service interfaces for the BDI Association Register. It defines how data is structured, how services are accessed, and the protocols used for communication.

{
"participant_id": "uuid",
"client_id": "string",
"legal_entity": {
"primary_legal_name": "string",
"lei": "string (20 chars)",
"coc_number": "string",
"eori": "string",
"country_code": "string (ISO 3166-1 alpha-2)",
"address": {
"line1": "string",
"line2": "string (optional)",
"postal_code": "string",
"city": "string",
"province": "string (optional)",
"country": "string (ISO 3166-1 alpha-2)"
},
"entity_legal_form": "string",
"registered_at": "string",
"direct_parent_lei": "string (optional)",
"ultimate_parent_lei": "string (optional)"
},
"participation": {
"status": "enum (pending|active|suspended|terminated)",
"identity_assurance_level": "enum (ial1|ial2|ial3)",
"joined_date": "datetime (ISO 8601)",
"renewal_date": "datetime (ISO 8601)"
},
"contacts": [{
"contact_id": "uuid",
"type": "enum (primary|technical|billing)",
"name": "string",
"email": "string",
"phone": "string (optional)"
}],
"created_at": "datetime",
"updated_at": "datetime"
}

Header:

{
"alg": "RS256",
"typ": "JWT",
"kid": "key-id"
}

Payload:

{
"iss": "https://association.ctn.network",
"sub": "client_id",
"aud": "https://ctn.network",
"iat": 1704063600,
"exp": 1704150000,
"nbf": 1704063600,
"jti": "unique-token-id",
"participant_claims": {
"legal_name": "string",
"lei": "string",
"coc_number": "string",
"eori": "string",
"country_code": "string",
"participation_status": "active",
"identity_assurance_level": "substantial",
"verified_at": "datetime"
}
}
POST /v1/applications
Content-Type: application/json
Authorization: Bearer <oauth_token>
{
"legal_name": "string",
"coc_number": "string",
"country_code": "string",
"contact_email": "string"
}
Response: 201 Created
{
"application_id": "uuid",
"status": "pending_documents",
"upload_url": "string"
}
GET /v1/participants/{clientId}
Authorization: Bearer <vad_token>
Response: 200 OK
{
// Participant profile as defined above
}
PATCH /v1/participants/{clientId}
Content-Type: application/json
Authorization: Bearer <vad_token>
{
"contacts": [/* updated contacts */],
"address": {/* updated address */}
}
Response: 200 OK
GET /v1/directory/lei/{lei}
Authorization: Bearer <vad_token>
Response: 200 OK
{
"client_id": "string",
"legal_name": "string",
"participation_status": "string",
"verified": true
}
GET /v1/directory/coc/{country_code}/{coc_number}
Authorization: Bearer <vad_token>
Response: 200 OK
{
"client_id": "string",
"legal_name": "string",
"participation_status": "string",
"verified": true
}
GET /v1/directory/eori/{eori}
Authorization: Bearer <vad_token>
Response: 200 OK
{
"client_id": "string",
"legal_name": "string",
"participation_status": "string",
"verified": true
}
POST /v1/tokens/vad
Content-Type: application/json
Authorization: Bearer <oauth_token>
{
"client_id": "string",
"audience": ["string"],
"validity_period": "number (seconds)"
}
Response: 200 OK
{
"vad_token": "string (JWT)",
"expires_at": "datetime",
"token_type": "Bearer"
}
POST /v1/tokens/validate
Content-Type: application/json
{
"token": "string (JWT)"
}
Response: 200 OK
{
"valid": true,
"claims": {/* token claims */},
"expires_at": "datetime"
}

Redis Cache Usage:

  • Key Pattern: lei:{lei}{client_id, legal_name, participation_status}
  • Key Pattern: coc:{country}:{number}{client_id, legal_name, participation_status}
  • Key Pattern: eori:{eori}{client_id, legal_name, participation_status}
  • TTL: 24 hours
  • Invalidation: On participant data update

Key Tables:

  • party_reference: Core party information
  • legal_entity: Legal entity details
  • legal_entity_number: External identifiers (LEI, CoC, EORI)
  • agreement: Membership agreements
  • agreement_item: Agreement line items
  • legal_entity_contact: Contact information
  • legal_entity_endpoint: API endpoints

Participant Events:

{
"event_id": "uuid",
"event_type": "enum",
"timestamp": "datetime",
"source": "association-register",
"data": {
"client_id": "string",
"event_details": {}
}
}

Event Types:

  • participant.application.created
  • participant.application.approved
  • participant.application.rejected
  • participant.activated
  • participant.suspended
  • participant.terminated
  • participant.profile.updated
  • vad.issued
  • vad.revoked
sequenceDiagram
    participant Client
    participant AuthServer as OAuth Server
    participant API as Association Register

    Client->>AuthServer: POST /oauth/token
    Note right of Client: grant_type=client_credentials<br/>client_id, client_secret
    AuthServer->>Client: Access Token (JWT)
    Client->>API: GET /v1/participants/{id}
    Note right of Client: Authorization: Bearer <token>
    API->>AuthServer: Validate Token
    AuthServer->>API: Token Valid + Claims
    API->>Client: Participant Data
sequenceDiagram
    participant Consumer as Data Consumer
    participant ASR as Association Register
    participant Provider as Data Provider

    Consumer->>ASR: Request VAD Token (OAuth client credentials)
    ASR->>ASR: Verify Participation
    ASR->>Consumer: VAD Token (JWS)
    Consumer->>Provider: Request data (Bearer VAD)
    Provider->>ASR: Fetch JWKS (cached)
    ASR->>Provider: Public keys
    Provider->>Provider: Validate VAD, apply local policy
    Provider->>Consumer: Data (or 403 Forbidden)
  • Format: 20 alphanumeric characters
  • Checksum validation (ISO 17442)
  • GLEIF verification required
  • Format varies by country
  • Netherlands: 8 digits
  • Cross-reference with Chamber API
  • Format: Country code + up to 15 characters
  • EU EORI validation service
  • Required for customs operations
  • 200 OK: Success
  • 201 Created: Resource created
  • 400 Bad Request: Invalid input
  • 401 Unauthorized: Missing/invalid authentication
  • 403 Forbidden: Insufficient permissions
  • 404 Not Found: Resource not found
  • 409 Conflict: Duplicate resource
  • 422 Unprocessable Entity: Validation error
  • 429 Too Many Requests: Rate limit exceeded
  • 500 Internal Server Error: Server error
  • 503 Service Unavailable: Service down
{
"error": {
"code": "string",
"message": "string",
"details": [
{
"field": "string",
"issue": "string"
}
],
"request_id": "uuid"
}
}
  • Directory lookups: < 200ms (cached)
  • Participant profile retrieval: < 500ms
  • VAD token generation: < 1 second
  • Participant updates: < 2 seconds
  • Support 1000+ concurrent requests
  • Handle 10,000+ directory lookups/minute
  • Process 100+ participant applications/day
  • 99.9% uptime SLA
  • Graceful degradation
  • Automatic failover
  • OAuth 2.0 Client Credentials
  • JWT-based access tokens
  • Mutual TLS (optional)
  • Role-based access control (RBAC)
  • Scope-based permissions
  • Participation-status enforcement
  • Encryption at rest (AES-256)
  • Encryption in transit (TLS 1.3)
  • PII masking in logs
  • GDPR compliance
  • API request rate
  • Response times (p50, p95, p99)
  • Error rates
  • Cache hit rates
  • Database query performance
  • Structured JSON logs
  • Correlation IDs
  • Request/response logging
  • Audit trail
  • SLA violations
  • Error rate spikes
  • Service degradation
  • Security events

Based on: BDI Association Register Format and Data Service.docx (processed 2025-10-05)

In samenwerking met

Connected Trade NetworkConclusionData in LogisticsContargoInland Terminals GroupVan Berkel