Naveera Partner API (1.0.0)

Download OpenAPI specification:

License: Proprietary

The Naveera Partner API enables trip brokers and credentialers to programmatically access trip data, manage webhook subscriptions, and receive real-time event notifications.

Use the Integration Guide sections in the sidebar for detailed documentation on authentication, webhooks, error handling, and code examples.

The API Reference section below contains the full endpoint specifications.

Overview

The Naveera Partner API enables trip brokers to programmatically access trip data they have brokered across all transportation provider tenants. As a broker, you can:

  • View trips you have brokered in real-time
  • Track status changes throughout the trip lifecycle
  • Receive webhook notifications when trip events occur
  • Query billing data for completed trips

Key Concepts

Term Description
Broker A trip coordination service that assigns trips to transportation providers
Provider A transportation company (tenant) that operationally fulfills trips
Partner ID Your unique identifier in the Naveera system
Broker Trip ID Your external reference ID for a trip

Architecture Overview

┌─────────────────────────────────────────────────────────────────────────┐
│                        YOUR BROKER SYSTEM                               │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│    ┌──────────────┐         ┌──────────────┐         ┌──────────────┐   │
│    │  Trip        │         │   Polling    │         │   Webhook    │   │
│    │  Lookup      │◄───────►│   Service    │◄───────►│   Receiver   │   │
│    └──────┬───────┘         └──────────────┘         └──────┬───────┘   │
│           │                                                  │          │
└───────────┼──────────────────────────────────────────────────┼──────────┘
            │                                                  │
            │ HTTPS + API Key                                  │ HTTPS POST
            ▼                                                  ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                      NAVEERA PARTNER API                                │
│                   /api/partner/v1/*                                     │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│   ┌──────────────┐    ┌──────────────┐    ┌──────────────┐              │
│   │   Trip       │    │   Webhook    │    │  Billing     │              │
│   │   Endpoints  │    │   Delivery   │    │  Endpoints   │              │
│   └──────────────┘    └──────────────┘    └──────────────┘              │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Getting Started

Step 1: Obtain API Credentials

Contact your Naveera account representative to register as a partner. You will receive:

  1. Key ID (nvr_pk_live_xxx): Public identifier for your API key
  2. Secret Key (nvr_sk_live_xxx): Private key for authentication

Important: Store your secret key securely. It is shown only once and cannot be retrieved again.

Step 2: Test Your Credentials

curl -X GET "https://api-sandbox.naveera.io/api/partner/v1/me" \
  -H "Authorization: Bearer nvr_pk_live_abc123:nvr_sk_live_xyz789"

Expected response:

{
  "partner_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "partner_type": "broker",
  "scopes": ["trips:read", "trips:lifecycle", "webhooks:manage"],
  "rate_limit_tier": "standard",
  "credential_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}

Register a webhook endpoint to receive real-time trip events:

curl -X POST "https://api-sandbox.naveera.io/api/partner/v1/webhooks/subscriptions" \
  -H "Authorization: Bearer nvr_pk_live_abc123:nvr_sk_live_xyz789" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-system.com/webhooks/naveera",
    "events": ["trip.status_changed", "trip.completed", "trip.canceled"],
    "name": "Production Webhook"
  }'

Authentication

API Key Authentication

All API requests (except public health endpoints) require authentication via Bearer token:

Authorization: Bearer {key_id}:{secret_key}

Example:

Authorization: Bearer nvr_pk_live_abc123def456:nvr_sk_live_xyz789jkl012mno345

Key Formats

Type Format Example
Key ID (Live) nvr_pk_live_{random} nvr_pk_live_abc123def456ghi789
Key ID (Test) nvr_pk_test_{random} nvr_pk_test_abc123def456ghi789
Secret (Live) nvr_sk_live_{random} nvr_sk_live_xyz789jkl012...
Secret (Test) nvr_sk_test_{random} nvr_sk_test_xyz789jkl012...

Scopes

Your API credentials are granted specific scopes:

Scope Description
trips:read Read trip data (list, detail, by-external-id)
trips:lifecycle Access trip status history
billing:read Access billing/invoice data
webhooks:manage Create and manage webhook subscriptions

Security Best Practices

  1. Never expose your secret key in client-side code, logs, or version control
  2. Use HTTPS for all API calls
  3. Rotate keys periodically by requesting new credentials
  4. Use separate keys for production and testing
  5. Implement IP allowlisting if supported by your firewall

API Endpoints

Public Endpoints (No Auth Required)

Method Endpoint Description
GET /health Service health status
GET /time Server time (for clock sync)
GET /changelog API version history

Trip Endpoints

Method Endpoint Scope Description
GET /trips trips:read List trips with filtering
GET /trips/{trip_id} trips:read Get trip by internal ID
GET /trips/by-external-id/{broker_trip_id} trips:read Get trip by your external ID
GET /trips/by-group/{group} trips:read List trips by logical status group
GET /trips/{trip_id}/status-history trips:lifecycle Get status change history

Webhook Endpoints

Method Endpoint Scope Description
GET /webhooks/subscriptions webhooks:manage List your subscriptions
POST /webhooks/subscriptions webhooks:manage Create subscription
GET /webhooks/subscriptions/{id} webhooks:manage Get subscription detail
PATCH /webhooks/subscriptions/{id} webhooks:manage Update subscription
DELETE /webhooks/subscriptions/{id} webhooks:manage Delete subscription
POST /webhooks/subscriptions/{id}/rotate-secret webhooks:manage Rotate signing secret
GET /webhooks/deliveries webhooks:manage List delivery attempts
GET /webhooks/deliveries/{id} webhooks:manage Get delivery detail
POST /webhooks/deliveries/{id}/retry webhooks:manage Retry failed delivery
GET /webhooks/events webhooks:manage Poll for events (fallback)

Observability Endpoints

Method Endpoint Scope Description
GET /rate-limit-status Any Check your rate limit usage
GET /me Any Get partner info

Broker Visibility Rules

What Brokers CAN See

As a broker, you can access trips where your partner_id is associated with the trip. For each trip, you can see:

Trip Identifiers:

  • Internal trip ID
  • Trip number
  • Your broker trip ID
  • External trip ID

Trip Information:

  • Trip type (scheduled, on_demand, will_call)
  • Trip date
  • Purpose
  • Current status

Schedule:

  • Scheduled pickup time
  • Actual pickup time
  • Actual dropoff time
  • Estimated/actual duration

Location (Address Only):

  • Street, city, state, zip code
  • Scheduled time
  • Completion time

Limited Passenger Info:

  • Passenger name only

Assignment Status:

  • Whether trip is assigned
  • Vehicle type (wheelchair, ambulatory, etc.)

Driver Info (limited):

  • Driver ID
  • Driver display name (first + last)

Vehicle Info (limited):

  • Vehicle ID
  • Vehicle label (nickname or number)
  • Make, model, year

Billing Summary:

  • Billing status (pending, invoiced, paid)
  • Total amount, base fare, mileage charge, wait time charge
  • Currency (ISO 4217)
  • Whether billing is finalized

Media & Artifacts:

  • Map snapshot URL (captured at trip completion)
  • Route snapshot URL (captured at trip completion)
  • Video artifacts (URL, camera position, start/end time, duration)

Cancellation Data:

  • Cancellation location (GPS coordinates, accuracy, timestamp) -- only for canceled trips

What Brokers CANNOT See

For privacy and security, the following fields are hidden from broker responses:

Category Hidden Fields
Organization organization_id, organization_name
Driver PII driver_phone, driver_license_number, driver_dob, driver_user_id
Vehicle Details license_plate, vin, telematics_data
Passenger PHI passenger_phone, passenger_email, passenger_dob, passenger_medicaid_number, passenger_special_requirements
Location Tracking latitude, longitude, location_notes (pickup/dropoff locations)
Internal Data metadata, internal_notes, created_by, deleted_at

Note: Driver ID and display name are now exposed via the driver object. Vehicle ID, label, make, model, and year are exposed via the vehicle object. Other driver/vehicle PII remains hidden.

Access Denied Behavior

If you attempt to access a trip that does not belong to your broker account, the API returns 404 Not Found (not 403 Forbidden). This prevents information leakage about trip existence.

Pagination and Filtering

Pagination Parameters

Parameter Type Default Description
page integer 1 Page number (1-indexed)
page_size integer 50 Items per page (max 100)

Pagination Response

{
  "items": [...],
  "total": 1234,
  "page": 1,
  "page_size": 50,
  "has_more": true
}

Trip Filtering

Parameter Type Example Description
status string assigned,in_progress Comma-separated status values
trip_date_from date 2024-01-01 Trips on or after this date
trip_date_to date 2024-01-31 Trips on or before this date
broker_trip_id string BRK-12345 Filter by your external ID
updated_since datetime 2024-01-30T00:00:00Z Trips updated after timestamp

Example: Filtered Trip List

curl -X GET "https://api.naveera.io/api/partner/v1/trips?status=assigned,in_progress&trip_date_from=2024-01-01&page_size=100" \
  -H "Authorization: Bearer nvr_pk_live_abc123:nvr_sk_live_xyz789"

Trip Status Groups

Use the /trips/by-group/{group} endpoint to query trips by logical status group instead of individual statuses:

Group Mapped Statuses Description
completed finished Trip finished successfully
canceled canceled, no_show Trip was canceled or passenger no-show
in_progress en_route, arrived, in_progress Trip is actively being executed
not_started All other statuses Trip is scheduled/pending

Example:

curl -X GET "https://api.naveera.io/api/partner/v1/trips/by-group/in_progress?page_size=100" \
  -H "Authorization: Bearer nvr_pk_live_abc123:nvr_sk_live_xyz789"

Using updated_since for Incremental Sync

To efficiently sync trip changes, track the last sync timestamp and use updated_since:

# Initial sync: Get all trips
curl "https://api.naveera.io/api/partner/v1/trips?page_size=100"

# Subsequent syncs: Only get changed trips
curl "https://api.naveera.io/api/partner/v1/trips?updated_since=2024-01-30T10:00:00Z"

Webhooks

Event Types

Event Trigger Description
trip.created New trip created with your broker ID Trip was assigned to a provider
trip.status_changed Trip status transition Any status change
trip.assigned Driver/vehicle assigned Trip is ready for pickup
trip.completed Trip marked complete Successful delivery
trip.canceled Trip canceled Trip will not be fulfilled
trip.eta_updated ETA recalculated Pickup/dropoff time changed

Webhook Payload Structure

{
  "event_id": "evt_abc123xyz789",
  "event_type": "trip.status_changed",
  "api_version": "2024-01-30",
  "created_at": "2024-01-30T10:15:30Z",
  "data": {
    "trip": {
      "id": 12345,
      "trip_number": "TRP-2024-001234",
      "broker_trip_id": "BRK-12345",
      "status": "in_progress",
      "previous_status": "assigned",
      "trip_date": "2024-01-30",
      "scheduled_pickup_time": "2024-01-30T14:00:00Z",
      "actual_pickup_time": "2024-01-30T14:05:00Z",
      "actual_dropoff_time": null,
      "pickup_address": "123 Main St, New York, NY 10001",
      "dropoff_address": "456 Oak Ave, New York, NY 10002",
      "passenger_name": "John Doe",
      "is_assigned": true,
      "vehicle_type": "wheelchair"
    }
  }
}

Note: Webhook payloads contain a flattened subset of trip data (addresses as strings). For the full trip object with structured driver, vehicle, billing_summary, videos, and other fields, use the REST API endpoints.

Webhook Headers

X-Naveera-Signature: t=1706612130,v1=abc123def456...
X-Naveera-Event-Type: trip.status_changed
X-Naveera-Event-Id: evt_abc123xyz789
Content-Type: application/json

Signature Verification

Always verify webhook signatures to ensure requests are from Naveera.

import hmac
import hashlib
import time

def verify_webhook_signature(
    payload: bytes,
    signature_header: str,
    secret: str,
    tolerance_seconds: int = 300
) -> bool:
    """
    Verify Naveera webhook signature.

    Args:
        payload: Raw request body bytes
        signature_header: Value of X-Naveera-Signature header
        secret: Your webhook signing secret
        tolerance_seconds: Maximum age of signature (default 5 minutes)

    Returns:
        True if signature is valid, False otherwise
    """
    # Parse signature header: t=timestamp,v1=signature
    parts = {}
    for part in signature_header.split(','):
        key, value = part.split('=', 1)
        parts[key] = value

    timestamp = int(parts.get('t', 0))
    expected_signature = parts.get('v1', '')

    # Check timestamp is recent (prevent replay attacks)
    current_time = int(time.time())
    if abs(current_time - timestamp) > tolerance_seconds:
        return False

    # Compute expected signature
    signed_payload = f"{timestamp}.{payload.decode('utf-8')}"
    computed_signature = hmac.new(
        secret.encode('utf-8'),
        signed_payload.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()

    # Constant-time comparison
    return hmac.compare_digest(computed_signature, expected_signature)

Webhook Best Practices

  1. Respond quickly: Return 200 OK within 5 seconds
  2. Process asynchronously: Queue webhook payloads for background processing
  3. Handle duplicates: Use event_id to deduplicate events
  4. Verify signatures: Always validate the X-Naveera-Signature header
  5. Use HTTPS: Webhook URLs must use HTTPS (HTTP rejected)

Retry Policy

If your endpoint fails, Naveera retries with exponential backoff:

Attempt Delay Cumulative Time
1 Immediate 0
2 5 seconds 5s
3 30 seconds 35s
4 2 minutes 2m 35s
5 10 minutes 12m 35s
6 1 hour 1h 12m
7 4 hours 5h 12m
8 (final) 24 hours 29h 12m

After 8 failures, the event is marked as failed. Use the events polling endpoint to catch up on missed events.

Polling Fallback

If your webhook endpoint is temporarily unavailable, use polling to catch up:

# Get events since last successful webhook
curl "https://api.naveera.io/api/partner/v1/webhooks/events?since=2024-01-30T00:00:00Z&limit=100" \
  -H "Authorization: Bearer nvr_pk_live_abc123:nvr_sk_live_xyz789"

Events are retained for 7 days.

Idempotency

For POST and PATCH operations, include an Idempotency-Key header to ensure safe retries:

curl -X POST "https://api.naveera.io/api/partner/v1/webhooks/subscriptions" \
  -H "Authorization: Bearer nvr_pk_live_abc123:nvr_sk_live_xyz789" \
  -H "Idempotency-Key: create-webhook-2024-01-30-001" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/webhook", "events": ["trip.status_changed"]}'

Idempotency Behavior

  • Same key, same request: Returns cached response (no re-execution)
  • Same key, different request: Returns error (key collision)
  • Key expiration: 24 hours

Replayed Response Header

When a cached response is returned:

X-Idempotency-Replayed: true

Rate Limiting

Rate Limit Tiers

Tier Per Minute Per Day Burst
Standard 60 10,000 100
Premium 300 100,000 500
Enterprise 1,000 Unlimited 2,000

Rate Limit Headers

Every response includes rate limit information:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1706612400

429 Too Many Requests

When rate limited, the response includes:

HTTP/1.1 429 Too Many Requests
Retry-After: 30
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1706612400

{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded. Retry after 30 seconds.",
    "details": {
      "limit": 60,
      "remaining": 0,
      "reset_at": 1706612400,
      "retry_after": 30
    }
  }
}

Handling Rate Limits

import time
import requests

def api_request_with_retry(url, headers, max_retries=3):
    """Make API request with rate limit retry handling."""
    for attempt in range(max_retries):
        response = requests.get(url, headers=headers)

        if response.status_code == 429:
            retry_after = int(response.headers.get('Retry-After', 60))
            print(f"Rate limited. Waiting {retry_after} seconds...")
            time.sleep(retry_after)
            continue

        return response

    raise Exception("Max retries exceeded")

Error Handling

Error Response Format

{
  "error": {
    "code": "TRIP_NOT_FOUND",
    "message": "Trip with id 12345 not found",
    "details": {}
  }
}

Common Error Codes

Code HTTP Status Description Action
UNAUTHORIZED 401 Invalid or missing credentials Check API key format
FORBIDDEN 403 Missing required scope Request scope upgrade
NOT_FOUND 404 Resource not found Verify ID/external ID
INVALID_STATUS 400 Invalid status filter value Check allowed values
RATE_LIMIT_EXCEEDED 429 Too many requests Wait and retry
SUBSCRIPTION_LIMIT_EXCEEDED 400 Too many webhook subscriptions Delete unused subscriptions
DELIVERY_NOT_RETRYABLE 400 Delivery not in failed status Check delivery status
INTERNAL_ERROR 500 Server error Retry with backoff

Validation Errors

{
  "code": "VALIDATION_ERROR",
  "message": "Request validation failed",
  "details": [
    {
      "loc": ["query", "page_size"],
      "msg": "ensure this value is less than or equal to 100",
      "type": "value_error.number.not_le"
    }
  ]
}

Best Practices

1. Use Webhooks for Real-Time Updates

Prefer webhooks over polling for real-time trip updates. Polling should only be used as a fallback.

2. Implement Incremental Sync

Use updated_since to fetch only changed trips since your last sync:

last_sync = get_last_sync_timestamp()
trips = api.get_trips(updated_since=last_sync)
process_trips(trips)
save_sync_timestamp(datetime.utcnow())

3. Handle Rate Limits Gracefully

Implement exponential backoff when rate limited:

def exponential_backoff(attempt, base_delay=1, max_delay=60):
    delay = min(base_delay * (2 ** attempt), max_delay)
    time.sleep(delay)

4. Use Idempotency Keys

Always include idempotency keys for webhook subscription operations to prevent duplicates.

5. Log Request IDs

Every response includes X-Request-ID. Log this for debugging:

response = requests.get(url, headers=headers)
request_id = response.headers.get('X-Request-ID')
logger.info(f"API request completed: {request_id}")

6. Validate Webhook Signatures

Never process webhooks without verifying the signature.

7. Handle Partial Failures

When processing multiple trips, handle individual failures gracefully:

for trip in trips:
    try:
        process_trip(trip)
    except Exception as e:
        logger.error(f"Failed to process trip {trip['id']}: {e}")
        # Continue with other trips

Code Examples

Python SDK Example

import requests
from dataclasses import dataclass
from typing import Optional, List
from datetime import datetime

@dataclass
class NaveeraPartnerClient:
    """Simple Naveera Partner API client."""

    base_url: str = "https://api.naveera.io/api/partner/v1"
    key_id: str = ""
    secret_key: str = ""

    @property
    def auth_header(self) -> dict:
        return {"Authorization": f"Bearer {self.key_id}:{self.secret_key}"}

    def list_trips(
        self,
        status: Optional[List[str]] = None,
        trip_date_from: Optional[str] = None,
        trip_date_to: Optional[str] = None,
        updated_since: Optional[str] = None,
        page: int = 1,
        page_size: int = 50
    ) -> dict:
        """List trips with optional filtering."""
        params = {"page": page, "page_size": page_size}
        if status:
            params["status"] = ",".join(status)
        if trip_date_from:
            params["trip_date_from"] = trip_date_from
        if trip_date_to:
            params["trip_date_to"] = trip_date_to
        if updated_since:
            params["updated_since"] = updated_since

        response = requests.get(
            f"{self.base_url}/trips",
            headers=self.auth_header,
            params=params
        )
        response.raise_for_status()
        return response.json()

    def get_trip(self, trip_id: int) -> dict:
        """Get trip by internal ID."""
        response = requests.get(
            f"{self.base_url}/trips/{trip_id}",
            headers=self.auth_header
        )
        response.raise_for_status()
        return response.json()

    def get_trip_by_external_id(self, broker_trip_id: str) -> dict:
        """Get trip by your external ID."""
        response = requests.get(
            f"{self.base_url}/trips/by-external-id/{broker_trip_id}",
            headers=self.auth_header
        )
        response.raise_for_status()
        return response.json()


# Usage
client = NaveeraPartnerClient(
    key_id="nvr_pk_live_abc123",
    secret_key="nvr_sk_live_xyz789"
)

# List active trips
trips = client.list_trips(status=["assigned", "in_progress"])
print(f"Found {trips['total']} active trips")

# Get trip by your external ID
trip = client.get_trip_by_external_id("BRK-12345")
print(f"Trip status: {trip['status']}")

Node.js Example

const axios = require('axios');
const crypto = require('crypto');

class NaveeraPartnerClient {
  constructor(keyId, secretKey, baseUrl = 'https://api.naveera.io/api/partner/v1') {
    this.keyId = keyId;
    this.secretKey = secretKey;
    this.baseUrl = baseUrl;
  }

  get authHeader() {
    return { Authorization: `Bearer ${this.keyId}:${this.secretKey}` };
  }

  async listTrips({ status, tripDateFrom, tripDateTo, updatedSince, page = 1, pageSize = 50 } = {}) {
    const params = new URLSearchParams({ page, page_size: pageSize });
    if (status) params.append('status', status.join(','));
    if (tripDateFrom) params.append('trip_date_from', tripDateFrom);
    if (tripDateTo) params.append('trip_date_to', tripDateTo);
    if (updatedSince) params.append('updated_since', updatedSince);

    const response = await axios.get(`${this.baseUrl}/trips?${params}`, {
      headers: this.authHeader,
    });
    return response.data;
  }

  async getTripByExternalId(brokerTripId) {
    const response = await axios.get(
      `${this.baseUrl}/trips/by-external-id/${encodeURIComponent(brokerTripId)}`,
      { headers: this.authHeader }
    );
    return response.data;
  }

  verifyWebhookSignature(payload, signatureHeader, secret, toleranceSeconds = 300) {
    const parts = Object.fromEntries(
      signatureHeader.split(',').map(p => p.split('=', 2))
    );
    const timestamp = parseInt(parts.t, 10);
    const expectedSignature = parts.v1;

    // Check timestamp
    const currentTime = Math.floor(Date.now() / 1000);
    if (Math.abs(currentTime - timestamp) > toleranceSeconds) {
      return false;
    }

    // Compute signature
    const signedPayload = `${timestamp}.${payload}`;
    const computedSignature = crypto
      .createHmac('sha256', secret)
      .update(signedPayload)
      .digest('hex');

    return crypto.timingSafeEqual(
      Buffer.from(computedSignature),
      Buffer.from(expectedSignature)
    );
  }
}

// Usage
const client = new NaveeraPartnerClient(
  'nvr_pk_live_abc123',
  'nvr_sk_live_xyz789'
);

// List active trips
const trips = await client.listTrips({
  status: ['assigned', 'in_progress']
});
console.log(`Found ${trips.total} active trips`);

// Webhook handler (Express.js)
app.post('/webhooks/naveera', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-naveera-signature'];
  const webhookSecret = process.env.NAVEERA_WEBHOOK_SECRET;

  if (!client.verifyWebhookSignature(req.body.toString(), signature, webhookSecret)) {
    return res.status(400).send('Invalid signature');
  }

  const event = JSON.parse(req.body);
  console.log(`Received event: ${event.event_type}`);

  // Process event asynchronously
  processEventAsync(event);

  res.status(200).send('OK');
});

FAQ

Q: How do I get API credentials?

Contact your Naveera account representative. They will register your organization as a partner and provide API credentials.

Q: Can I access trips from all providers?

You can only access trips where your organization is the broker. Each trip has a partner_id that links to your broker account.

Q: Why can't I see driver or vehicle details?

For privacy and safety reasons, driver and vehicle PII is not exposed to brokers. You can see assignment status and vehicle type (wheelchair/ambulatory) but not identifying information.

Q: How do I look up a trip by my reference number?

Use the /trips/by-external-id/{broker_trip_id} endpoint with your external reference ID.

Q: What happens if my webhook endpoint is down?

Naveera retries failed webhooks up to 8 times over approximately 29 hours. If all retries fail, use the /webhooks/events polling endpoint to catch up on missed events.

Q: How do I handle duplicate webhook events?

Use the event_id field to deduplicate. Store processed event IDs and skip any duplicates.

Q: Can I test with sandbox data?

Yes, use the sandbox environment (api-sandbox.naveera.io) with test API keys (nvr_pk_test_xxx).

Q: How do I upgrade my rate limit tier?

Contact your Naveera account representative to discuss upgrading to Premium or Enterprise tier.

Changelog

v1.1.0 (2026-02-17)

New Endpoints

  • GET /trips/by-group/{group} -- List trips filtered by logical status group (completed, canceled, in_progress, not_started)

New Trip Data Fields

  • driver -- Limited driver identity (ID and display name) when a driver is assigned
  • vehicle -- Limited vehicle info (ID, label, make, model, year) when a vehicle is assigned
  • billing_summary -- Billing status, total amount, base fare, mileage/wait time charges, and finalization flag
  • map_snapshot_url -- Map snapshot image URL captured at trip completion
  • route_snapshot_url -- Route snapshot image URL captured at trip completion
  • videos -- Video artifacts with camera position and time range metadata
  • cancellation_location -- GPS coordinates where trip cancellation occurred

Updated Enums

  • Trip types updated to: scheduled, on_demand, will_call

v1.0.0 (2026-02-06)

Initial Release

  • Trip read endpoints for brokers
  • Trip status history endpoint
  • Webhook subscription management
  • Webhook delivery with retry
  • Event polling fallback
  • Idempotency key support
  • Rate limiting (Standard/Premium/Enterprise)
  • Audit logging for compliance

Observability

Health checks, server time, and API information endpoints. /health, /time, and /changelog are public (no auth required).

Health Check

Check the health status of the Partner API and its dependencies.

Responses

Response samples

Content type
application/json
{
  • "status": "string",
  • "version": "string",
  • "timestamp": "2019-08-24T14:15:22Z",
  • "dependencies": {
    }
}

Server Time

Get the current server time for clock synchronization.

Responses

Response samples

Content type
application/json
{
  • "server_time": "2019-08-24T14:15:22Z",
  • "timezone": "UTC",
  • "unix_timestamp": 0
}

API Changelog

Get API version history and deprecation notices.

Responses

Response samples

Content type
application/json
{
  • "current_version": "string",
  • "entries": [
    ]
}

Rate Limit Status

Get current rate limit status for your partner account.

Authorizations:
BearerAuth
header Parameters
Authorization (string) or Authorization (null) (Authorization)

Responses

Response samples

Content type
application/json
{
  • "tier": "string",
  • "limits": {
    },
  • "current_usage": {
    },
  • "remaining": {
    },
  • "reset_seconds": 0
}

Partner Info

Get information about the authenticated partner.

Authorizations:
BearerAuth
header Parameters
Authorization (string) or Authorization (null) (Authorization)

Responses

Response samples

Content type
application/json
{ }

Trips

Trip read access for brokers. All trips are filtered by broker ownership (ABAC) and sensitive fields are redacted.

List trips

List trips brokered by the authenticated partner with pagination and filtering.

Authorizations:
BearerAuth
query Parameters
Status (string) or Status (null) (Status)

Filter by status (comma-separated, e.g., 'assigned,in_progress')

Trip Date From (string) or Trip Date From (null) (Trip Date From)

Filter trips on or after this date

Trip Date To (string) or Trip Date To (null) (Trip Date To)

Filter trips on or before this date

Broker Trip Id (string) or Broker Trip Id (null) (Broker Trip Id)

Filter by broker's external trip ID

Updated Since (string) or Updated Since (null) (Updated Since)

Filter trips updated after this timestamp

page
integer (Page) >= 1
Default: 1

Page number (1-indexed)

page_size
integer (Page Size) [ 1 .. 100 ]
Default: 50

Items per page (max 100)

header Parameters
Authorization (string) or Authorization (null) (Authorization)

Responses

Response samples

Content type
application/json
{
  • "items": [
    ],
  • "total": 0,
  • "page": 0,
  • "page_size": 0,
  • "has_more": true
}

List trips by status group

List trips filtered by a logical status group. Groups map to underlying statuses: completed (finished), canceled (canceled, no_show), in_progress (en_route, arrived, in_progress), not_started (all other statuses).

Authorizations:
BearerAuth
path Parameters
group
required
string (TripGroup)
Enum: "completed" "canceled" "in_progress" "not_started"

Logical trip status groups for partner-facing API.

Maps granular internal statuses to simplified groups:

  • completed: Trip finished successfully
  • canceled: Trip was canceled or passenger no-showed
  • in_progress: Trip is actively being executed
  • not_started: Trip is scheduled/pending but not yet underway

Any status not explicitly mapped to the first three groups is treated as not_started per business requirements.

query Parameters
Trip Date From (string) or Trip Date From (null) (Trip Date From)

Filter trips on or after this date

Trip Date To (string) or Trip Date To (null) (Trip Date To)

Filter trips on or before this date

Updated Since (string) or Updated Since (null) (Updated Since)

Filter trips updated after this timestamp

page
integer (Page) >= 1
Default: 1

Page number (1-indexed)

page_size
integer (Page Size) [ 1 .. 100 ]
Default: 50

Items per page (max 100)

header Parameters
Authorization (string) or Authorization (null) (Authorization)

Responses

Response samples

Content type
application/json
{
  • "group": "completed",
  • "items": [
    ],
  • "total": 0,
  • "page": 0,
  • "page_size": 0,
  • "has_more": true
}

Get trip by external ID

Get a single trip by the broker's external reference ID.

Authorizations:
BearerAuth
path Parameters
broker_trip_id
required
string (Broker Trip Id)
header Parameters
Authorization (string) or Authorization (null) (Authorization)

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "trip_number": "string",
  • "broker_trip_id": "string",
  • "external_trip_id": "string",
  • "trip_type": "scheduled",
  • "trip_date": "2019-08-24",
  • "purpose": "string",
  • "status": "scheduled",
  • "scheduled_pickup_time": "2019-08-24T14:15:22Z",
  • "actual_pickup_time": "2019-08-24T14:15:22Z",
  • "actual_dropoff_time": "2019-08-24T14:15:22Z",
  • "estimated_duration_minutes": 0,
  • "actual_duration_minutes": 0,
  • "pickup": {
    },
  • "dropoff": {
    },
  • "passenger_name": "string",
  • "is_assigned": false,
  • "vehicle_type": "string",
  • "driver": {
    },
  • "vehicle": {
    },
  • "map_snapshot_url": "string",
  • "route_snapshot_url": "string",
  • "videos": [
    ],
  • "cancellation_location": {
    },
  • "billing_summary": {
    },
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Get trip detail

Get detailed information for a single trip.

Authorizations:
BearerAuth
path Parameters
trip_id
required
integer (Trip Id)
header Parameters
Authorization (string) or Authorization (null) (Authorization)

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "trip_number": "string",
  • "broker_trip_id": "string",
  • "external_trip_id": "string",
  • "trip_type": "scheduled",
  • "trip_date": "2019-08-24",
  • "purpose": "string",
  • "status": "scheduled",
  • "scheduled_pickup_time": "2019-08-24T14:15:22Z",
  • "actual_pickup_time": "2019-08-24T14:15:22Z",
  • "actual_dropoff_time": "2019-08-24T14:15:22Z",
  • "estimated_duration_minutes": 0,
  • "actual_duration_minutes": 0,
  • "pickup": {
    },
  • "dropoff": {
    },
  • "passenger_name": "string",
  • "is_assigned": false,
  • "vehicle_type": "string",
  • "driver": {
    },
  • "vehicle": {
    },
  • "map_snapshot_url": "string",
  • "route_snapshot_url": "string",
  • "videos": [
    ],
  • "cancellation_location": {
    },
  • "billing_summary": {
    },
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Get trip status history

Get the status transition history for a trip.

Authorizations:
BearerAuth
path Parameters
trip_id
required
integer (Trip Id)
query Parameters
From Date (string) or From Date (null) (From Date)

Filter history from this timestamp

To Date (string) or To Date (null) (To Date)

Filter history until this timestamp

header Parameters
Authorization (string) or Authorization (null) (Authorization)

Responses

Response samples

Content type
application/json
{
  • "trip_id": 0,
  • "broker_trip_id": "string",
  • "history": [
    ]
}

Webhooks

Webhook subscription and delivery management. Create subscriptions to receive real-time trip events.

List webhook subscriptions

List all webhook subscriptions for the authenticated partner.

Authorizations:
BearerAuth
header Parameters
Authorization (string) or Authorization (null) (Authorization)

Responses

Response samples

Content type
application/json
{
  • "items": [
    ],
  • "total": 0
}

Create webhook subscription

Create a new webhook subscription. The signing secret is returned only once.

Authorizations:
BearerAuth
header Parameters
Authorization (string) or Authorization (null) (Authorization)
Request Body schema: application/json
required
url
required
string <uri> (Url) [ 1 .. 2083 ] characters

Webhook endpoint URL (must be HTTPS)

events
Array of strings (Events)
Items Enum: "trip.created" "trip.status_changed" "trip.assigned" "trip.completed" "trip.canceled" "trip.eta_updated"

Event types to receive (empty = all events)

Name (string) or Name (null) (Name)

Human-readable name for this subscription

Description (string) or Description (null) (Description)

Description of this webhook endpoint

Responses

Request samples

Content type
application/json
{
  • "events": [
    ],
  • "name": "string",
  • "description": "string"
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "partner_id": "6a3a39f6-861b-4a48-b868-5de838400e06",
  • "url": "string",
  • "events": [
    ],
  • "name": "string",
  • "description": "string",
  • "is_active": true,
  • "consecutive_failures": 0,
  • "last_success_at": "2019-08-24T14:15:22Z",
  • "last_failure_at": "2019-08-24T14:15:22Z",
  • "disabled_at": "2019-08-24T14:15:22Z",
  • "disabled_reason": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z",
  • "secret": "string"
}

Get webhook subscription

Get details of a specific webhook subscription.

Authorizations:
BearerAuth
path Parameters
subscription_id
required
string <uuid> (Subscription Id)
header Parameters
Authorization (string) or Authorization (null) (Authorization)

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "partner_id": "6a3a39f6-861b-4a48-b868-5de838400e06",
  • "url": "string",
  • "events": [
    ],
  • "name": "string",
  • "description": "string",
  • "is_active": true,
  • "consecutive_failures": 0,
  • "last_success_at": "2019-08-24T14:15:22Z",
  • "last_failure_at": "2019-08-24T14:15:22Z",
  • "disabled_at": "2019-08-24T14:15:22Z",
  • "disabled_reason": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Update webhook subscription

Update a webhook subscription's URL, events, or status.

Authorizations:
BearerAuth
path Parameters
subscription_id
required
string <uuid> (Subscription Id)
header Parameters
Authorization (string) or Authorization (null) (Authorization)
Request Body schema: application/json
required
Url (string) or Url (null) (Url)

New webhook endpoint URL

Array of Events (strings) or Events (null) (Events)

New event filter (empty = all events)

Name (string) or Name (null) (Name)
Description (string) or Description (null) (Description)
Is Active (boolean) or Is Active (null) (Is Active)

Enable/disable subscription

Responses

Request samples

Content type
application/json
{
  • "events": [
    ],
  • "name": "string",
  • "description": "string",
  • "is_active": true
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "partner_id": "6a3a39f6-861b-4a48-b868-5de838400e06",
  • "url": "string",
  • "events": [
    ],
  • "name": "string",
  • "description": "string",
  • "is_active": true,
  • "consecutive_failures": 0,
  • "last_success_at": "2019-08-24T14:15:22Z",
  • "last_failure_at": "2019-08-24T14:15:22Z",
  • "disabled_at": "2019-08-24T14:15:22Z",
  • "disabled_reason": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Delete webhook subscription

Delete a webhook subscription. Pending deliveries will be canceled.

Authorizations:
BearerAuth
path Parameters
subscription_id
required
string <uuid> (Subscription Id)
header Parameters
Authorization (string) or Authorization (null) (Authorization)

Responses

Response samples

Content type
application/json
{
  • "error": {
    }
}

Rotate webhook secret

Rotate the signing secret for a webhook subscription. The new secret is returned only once.

Authorizations:
BearerAuth
path Parameters
subscription_id
required
string <uuid> (Subscription Id)
header Parameters
Authorization (string) or Authorization (null) (Authorization)

Responses

Response samples

Content type
application/json
{
  • "secret": "string",
  • "rotated_at": "2019-08-24T14:15:22Z"
}

List webhook deliveries

List webhook delivery attempts with optional filtering.

Authorizations:
BearerAuth
query Parameters
Subscription Id (string) or Subscription Id (null) (Subscription Id)

Filter by subscription ID

Event Type (string) or Event Type (null) (Event Type)

Filter by event type

WebhookDeliveryStatus (string) or Status (null) (Status)

Filter by delivery status

page
integer (Page) >= 1
Default: 1

Page number (1-indexed)

page_size
integer (Page Size) [ 1 .. 100 ]
Default: 50

Items per page (max 100)

header Parameters
Authorization (string) or Authorization (null) (Authorization)

Responses

Response samples

Content type
application/json
{
  • "items": [
    ],
  • "total": 0,
  • "page": 0,
  • "page_size": 0,
  • "has_more": true
}

Get delivery details

Get details of a specific webhook delivery attempt.

Authorizations:
BearerAuth
path Parameters
delivery_id
required
integer (Delivery Id)
header Parameters
Authorization (string) or Authorization (null) (Authorization)

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "subscription_id": "aa11a4c2-a467-43db-b413-c4ab0f5cf627",
  • "event_id": "string",
  • "status": "pending",
  • "attempt_count": 0,
  • "max_attempts": 0,
  • "next_retry_at": "2019-08-24T14:15:22Z",
  • "response_status": 0,
  • "response_time_ms": 0,
  • "error_message": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "first_attempted_at": "2019-08-24T14:15:22Z",
  • "last_attempted_at": "2019-08-24T14:15:22Z",
  • "delivered_at": "2019-08-24T14:15:22Z",
  • "failed_at": "2019-08-24T14:15:22Z"
}

Retry failed delivery

Manually retry a failed webhook delivery.

Authorizations:
BearerAuth
path Parameters
delivery_id
required
integer (Delivery Id)
header Parameters
Authorization (string) or Authorization (null) (Authorization)

Responses

Response samples

Content type
application/json
{
  • "delivery_id": 0,
  • "event_id": "string",
  • "status": "retrying",
  • "next_retry_at": "2019-08-24T14:15:22Z",
  • "message": "Retry scheduled"
}

Poll for webhook events

Poll for webhook events. Use this as a fallback when your webhook endpoint is unavailable.

Authorizations:
BearerAuth
query Parameters
Since (string) or Since (null) (Since)

Return events created after this timestamp (ISO 8601)

Event Type (string) or Event Type (null) (Event Type)

Filter by event type

limit
integer (Limit) [ 1 .. 1000 ]
Default: 100

Maximum events to return

header Parameters
Authorization (string) or Authorization (null) (Authorization)

Responses

Response samples

Content type
application/json
{
  • "items": [
    ],
  • "total": 0,
  • "has_more": true
}