Platform Docs

Welcome. The Sail API provides on-demand delivery services. Connect to multiple providers (Bolt, Uber, Yango) through a single, unified API.

You're not signed in. Sign in via your invite to manage keys.

All API requests should be made to https://api.sailrides.co. All endpoints are versioned and prefixed with /v1.

1Create your API key

Sign in to your Sail Platform account to manage your API key, or register your interest to get started.

For security, load your API key from environment variables (for example via .env) and never store it in browser storage.

2Connect delivery providers

Connect the accounts you'll use when booking deliveries via the API. You can disconnect anytime.

SAIL
bolt
uber
yango

3Try a request

Run a quick quote search using your SAIL_API_KEY environment variable.

Get Delivery Quote
Successful responses include header X-Sail-Status: Smooth Sailing.

Overview

The Sail API provides a comprehensive delivery platform that connects you to multiple providers through a single, unified interface.

Features

  • Multi-Provider Support: Connect to Bolt, Uber, and Yango through one API
  • Unified Interface: Consistent request/response format across all providers
  • Real-time Pricing: Get accurate quotes and delivery estimates
  • Provider Management: Easily connect and disconnect provider accounts
  • Status Tracking: Monitor delivery progress with comprehensive status updates

Architecture

The Sail API acts as a unified layer on top of multiple delivery providers, abstracting away the differences between their individual APIs. This allows you to integrate once and get access to multiple providers seamlessly.

Base URL

All API requests should be made to https://api.sailrides.co. All endpoints are versioned and prefixed with /v1.

Authentication

All API requests must be authenticated using your API key in the Authorization header:

Getting Your API Key

To get your API key:

  • Sign in to your Sail Platform account
  • Click “Create API Key” in the Getting Started section
  • Copy your key immediately - it won’t be shown again for security reasons
  • Store it securely in your environment variables

API Key Format

API keys follow the format: sail_prod_{theme}_{random_string}

  • sail_prod: Production key prefix
  • {theme}: Nautical theme (anchor, voyage, compass, etc.)
  • {random_string}: Cryptographically secure random string

Security Best Practices

  • Store your API key in environment variables, not in code
  • Never commit API keys to version control
  • Rotate your API key if you suspect it’s been compromised
  • Use HTTPS for all API requests

Rate Limits

API requests are rate limited per API key to ensure fair usage:

  • Quotes: 100 requests per minute
  • Deliveries: 50 requests per minute
  • Status Checks: 200 requests per minute

Rate limit headers are included in all responses:

Handling Rate Limits

When you receive a 429 Too Many Requests response:

  • Check the X-RateLimit-Reset header for when the limit resets
  • Implement exponential backoff for retries
  • Consider webhook notifications instead of polling for high-frequency updates

Get Quotes

Get delivery quotes from all connected providers for a given pickup and destination.

POST /v1/deliveries/quotes

Request Body

  • pickup.lat, pickup.lng: Pickup coordinates (decimal degrees)
  • destination.lat, destination.lng: Destination coordinates (decimal degrees)
  • pickup.address, destination.address: Human-readable addresses for reference

Response

  • quotes.id: Unique quote identifier for booking
  • quotes.provider: Provider name (bolt, uber, yango)
  • quotes.service_name: Display name of the service
  • quotes.price.amount: Total price in local currency
  • quotes.price.currency: 3-letter currency code
  • quotes.eta_minutes: Estimated time to pickup in minutes
  • quotes.expires_at: Quote expiration time (ISO 8601)

Example Request

Get Delivery Quote

Error Handling

Common Error Responses:

  • invalid_location: Coordinates outside service area
  • no_providers_available: No providers servicing the route
  • rate_limited: Too many quote requests
  • invalid_coordinates: Malformed coordinate data

Deliveries

Manage delivery lifecycle from booking to completion.

Create Delivery

Book a delivery using a previously obtained quote ID.

POST /v1/deliveries
  • quoteId: Valid quote ID (must not be expired)
  • webhookUrl: URL to receive status updates
  • customerInfo: Customer contact information
  • notes: Additional delivery instructions
Create Delivery

Get Delivery

Retrieve delivery status and details.

GET /v1/deliveries/{deliveryId}
Get Delivery

Delivery Status Flow

Deliveries progress through these statuses:

  • pending - Awaiting provider acceptance
  • accepted - Driver assigned, en route to pickup
  • arriving - Driver arriving at pickup location
  • in_progress - Package in transit, en route to destination
  • completed - Delivery completed successfully
  • cancelled - Delivery cancelled by user or provider
  • failed - Delivery failed (no-show, payment issue, etc.)

Cancel Delivery

Cancel an active delivery.

POST /v1/deliveries/{deliveryId}/cancel

Note: Only deliveries in pending or accepted status can be cancelled.

  • customer_request: Customer requested cancellation
  • provider_unavailable: Provider unable to complete
  • payment_failed: Payment processing failed
Cancel Delivery

Status Polling

Status polling is an alternative to webhooks for monitoring delivery progress. Poll delivery status at regular intervals to track updates.

When to Use Polling

Use polling when:

  • Your application cannot receive webhook requests
  • You need real-time status updates for specific deliveries
  • You want to supplement webhook notifications
  • You’re building a simple application without webhook infrastructure

Use webhooks when:

  • You need to monitor many deliveries simultaneously
  • You want instant notifications
  • You want to reduce API calls
  • You have server infrastructure to receive webhooks

Polling Strategy

Recommended polling frequencies based on delivery status:

  • Active statuses (pending, accepted, arriving): Every 30-60 seconds
  • In-progress: Every 60-120 seconds
  • Final statuses (completed, cancelled, failed): Stop polling

Rate Limiting Considerations:

  • Respect the 50 requests/minute limit for delivery endpoints
  • Implement backoff for failed requests
  • Use exponential backoff for rate-limited responses

Implementation Example

Delivery Status Polling

Best Practices

  • Set reasonable timeouts - Don’t wait indefinitely for responses
  • Handle rate limits gracefully - Implement exponential backoff
  • Store delivery state - Avoid re-polling completed deliveries
  • Use conditional requests - Check Last-Modified headers if available
  • Monitor API usage - Track your request count to avoid hitting limits
  • Have a fallback - Consider switching to webhooks if polling becomes inefficient

Webhooks

Webhooks provide real-time notifications when delivery status changes occur. Instead of constantly polling our API, you can receive immediate updates by configuring webhook endpoints.

Configuration

Configure your webhook URL when creating a delivery by including the webhookUrl field in your request. The webhook URL will receive real-time notifications for that delivery.

Webhook URL Requirements:

  • Must be publicly accessible
  • Should respond within 5 seconds
  • Must return a 200 status code
  • Supports HTTPS endpoints only

Webhook Events

The following events are sent via webhooks:

EventDescriptionWhen Sent
delivery.createdNew delivery createdImmediately after creation
delivery.status_updatedDelivery status changedWhen status changes
delivery.completedDelivery completed successfullyWhen delivery reaches completed status
delivery.cancelledDelivery was cancelledWhen delivery is cancelled
delivery.failedDelivery failedWhen delivery fails

Webhook Payload

All webhook payloads contain this structure:

Payload Fields:

  • id: Unique webhook event identifier
  • event: Type of event that occurred
  • created_at: Timestamp when webhook was sent
  • data: Event-specific data

Security

All webhook requests include security headers:

Headers:

  • X-Sail-Signature: HMAC-SHA256 signature of the payload
  • X-Sail-Timestamp: Unix timestamp of when webhook was sent

Signature Verification: The signature is calculated as: HMAC-SHA256(secret, payload)

Webhook Signature Verification

Security Best Practices:

  • Always verify webhook signatures
  • Reject requests older than 5 minutes
  • Use HTTPS for webhook endpoints
  • Keep your webhook secret secure
  • Implement rate limiting

Delivery and Retries

Reliability Features:

  • Automatic retries for failed deliveries
  • Exponential backoff retry strategy
  • Maximum of 5 retry attempts
  • 5-second timeout per attempt

Retry Schedule:

  • Attempt 1: Immediate
  • Attempt 2: 30 seconds later
  • Attempt 3: 2 minutes later
  • Attempt 4: 10 minutes later
  • Attempt 5: 30 minutes later

If all retries fail, the webhook is marked as failed and you can view failed attempts in your dashboard.

Testing Webhooks

Use these tools to test webhooks during development:

  • ngrok - Expose local endpoints to the internet
  • webhook.site - Temporary webhook URL for testing
  • RequestBin - Inspect webhook requests
  • Local testing - Use curl to simulate webhook calls

Best Practices

  • Respond quickly - Return within 5 seconds
  • Process asynchronously - Don’t block webhook delivery
  • Idempotency - Handle duplicate webhook deliveries
  • Retry strategy - Implement your own retry logic for critical failures
  • Logging - Log all webhook events for debugging
  • Have fallback - Use polling if webhooks fail repeatedly

Error Handling

The API uses conventional HTTP status codes and returns detailed error information in JSON format to help you troubleshoot issues.

Error Response Format

All error responses follow this consistent format:

  • code: Machine-readable error code for programmatic handling
  • message: Human-readable error description
  • details: Additional context and debugging information
  • requestId: Unique identifier for the request (useful for support)

HTTP Status Codes

  • 200 OK: Request successful
  • 201 Created: Resource created successfully
  • 400 Bad Request: Invalid JSON or missing required fields
  • 401 Unauthorized: Invalid or missing API key
  • 403 Forbidden: Insufficient permissions
  • 404 Not Found: Invalid delivery ID or endpoint
  • 409 Conflict: Resource state conflict
  • 422 Unprocessable Entity: Valid JSON but invalid data
  • 429 Rate Limited: Too many requests
  • 500 Internal Server Error: Unexpected server error
  • 502 Bad Gateway: Upstream provider error
  • 503 Service Unavailable: Temporary service outage

Common Error Codes

Authentication Errors

  • invalid_api_key (401): API key is invalid or revoked
  • missing_api_key (401): API key not provided in header
  • expired_api_key (401): API key has expired

Request Validation Errors

  • invalid_json (400): Request body is not valid JSON
  • missing_required_field (422): Required field is missing
  • invalid_field_value (422): Field value is invalid
  • field_too_long (422): Field value exceeds maximum length

Quote Errors

  • invalid_quote (400): Quote ID is invalid or expired
  • quote_not_found (404): Quote does not exist
  • quote_expired (400): Quote has expired
  • quote_used (400): Quote has already been used

Delivery Errors

  • delivery_not_found (404): Delivery does not exist
  • delivery_not_cancellable (400): Delivery cannot be cancelled
  • provider_unavailable (502): Provider service is down
  • insufficient_funds (400): Insufficient funds for delivery

Rate Limiting Errors

  • rate_limit_exceeded (429): Rate limit exceeded
  • daily_limit_exceeded (429): Daily rate limit exceeded

Response Headers

All responses include these important headers:

Success Responses:

Error Responses:

  • Smooth Sailing: Request successful
  • Rough Seas: Client error (4xx)
  • Becalmed: Server error (5xx)

Error Handling Best Practices

1. Always Check HTTP Status

2. Handle Rate Limits Gracefully

3. Use Request IDs for Debugging

4. Implement Exponential Backoff

5. Log Errors Appropriately

Troubleshooting Guide

Common Issues and Solutions

  • 401 Unauthorized: Verify API key in Authorization header format: ApiKey your_key
  • 429 Rate Limited: Implement rate limiting and exponential backoff
  • Quote expired: Request a new quote before creating delivery
  • Delivery not found: Verify delivery ID and account permissions
  • Provider unavailable: Try again later or use different provider