API Access

Access your tour data programmatically via the REST API

API Access

A Grand Tour provides a REST API that lets you access your tour data programmatically. Whether you’re building a custom integration, writing automation scripts, or just want to back up your data, the API gives you full programmatic control.

What is the API?

The A Grand Tour API is a RESTful HTTP API that returns JSON. It’s the same API used internally by:

  • The web application itself
  • The iOS companion app
  • Third-party integrations

This means it’s well-tested, performant, and continuously maintained.

Authentication

All API requests require authentication using a Bearer token.

Generating an API Token

  1. Go to Account SettingsAPI Tokens
  2. Click Generate New Token
  3. Give it a descriptive name (e.g., “Backup Script”, “iOS App”)
  4. Click Create
  5. Copy the token immediately—it won’t be shown again

Important: Treat API tokens like passwords. They provide full access to your account data.

Using the Token

Include the token in the Authorization header of every request:

GET /api/v1/tours HTTP/1.1
Host: a-grand-tour.com
Authorization: Bearer YOUR_TOKEN_HERE

Example with curl:

curl https://a-grand-tour.com/api/v1/tours \
  -H "Authorization: Bearer YOUR_TOKEN_HERE"

Base URL

All API endpoints are prefixed with:

https://a-grand-tour.com/api/v1

Key Endpoints

The API provides access to all major entities in A Grand Tour. Here are the most commonly used endpoints:

Tours

GET    /api/v1/tours              # List all your tours
GET    /api/v1/tours/:id          # Get a specific tour
POST   /api/v1/tours              # Create a new tour
PATCH  /api/v1/tours/:id          # Update a tour
DELETE /api/v1/tours/:id          # Delete a tour

Trips

GET    /api/v1/tours/:tour_id/trips           # List trips in a tour
GET    /api/v1/trips/:id                      # Get a specific trip
POST   /api/v1/tours/:tour_id/trips           # Create a new trip
PATCH  /api/v1/trips/:id                      # Update a trip
DELETE /api/v1/trips/:id                      # Delete a trip

Itinerary Items

GET    /api/v1/trips/:trip_id/itinerary       # Get trip itinerary
POST   /api/v1/trips/:trip_id/itinerary       # Add itinerary item
PATCH  /api/v1/itinerary/:id                  # Update item
DELETE /api/v1/itinerary/:id                  # Delete item

Routes

GET    /api/v1/trips/:trip_id/route           # Get trip route (GeoJSON)
POST   /api/v1/trips/:trip_id/route/waypoints # Add waypoint
PATCH  /api/v1/waypoints/:id                  # Update waypoint
DELETE /api/v1/waypoints/:id                  # Remove waypoint

Datasets (POIs, Custom Points)

GET    /api/v1/tours/:tour_id/datasets        # List datasets
GET    /api/v1/datasets/:id                   # Get dataset (GeoJSON)
POST   /api/v1/tours/:tour_id/datasets        # Create dataset
POST   /api/v1/datasets/:id/points            # Add point to dataset

Documents

GET    /api/v1/tours/:tour_id/documents       # List documents
GET    /api/v1/documents/:id                  # Get document content
POST   /api/v1/tours/:tour_id/documents       # Create document
PATCH  /api/v1/documents/:id                  # Update document
DELETE /api/v1/documents/:id                  # Delete document

Example Requests

List Your Tours

curl -X GET https://a-grand-tour.com/api/v1/tours \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json"

Response:

{
  "data": [
    {
      "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
      "name": "Silk Road 2026",
      "subtitle": "Istanbul to Kashgar",
      "is_public": true,
      "url_slug": "silk-road-2026",
      "inserted_at": "2025-11-15T10:30:00Z",
      "updated_at": "2026-01-20T14:22:00Z"
    }
  ]
}

Create a New Trip

curl -X POST https://a-grand-tour.com/api/v1/tours/TOUR_ID/trips \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Turkey to Georgia",
    "subtitle": "Eastern Turkey and the Caucasus",
    "start_date": "2026-05-01",
    "end_date": "2026-05-21",
    "status": "planning"
  }'

Get Route as GeoJSON

curl -X GET https://a-grand-tour.com/api/v1/trips/TRIP_ID/route \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Accept: application/geo+json"

Response:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "LineString",
        "coordinates": [[28.9784, 41.0082], [35.8917, 31.9539], ...]
      },
      "properties": {
        "trip_id": "...",
        "distance_km": 1847.3,
        "duration_hrs": 28.5
      }
    }
  ]
}

Update a Document

curl -X PATCH https://a-grand-tour.com/api/v1/documents/DOC_ID \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Updated Title",
    "content": "# New Content\n\nRevised planning notes..."
  }'

Rate Limiting

To protect the service and ensure fair usage, the API enforces rate limits:

  • Standard users: 100 requests per minute
  • Premium users: 300 requests per minute

When you exceed the rate limit, you’ll receive a 429 Too Many Requests response:

{
  "error": "Rate limit exceeded",
  "retry_after": 42
}

The retry_after field indicates how many seconds to wait before retrying.

Best Practices

  • Cache responses when appropriate
  • Use batch endpoints when available
  • Implement exponential backoff for retries
  • Don’t poll—use webhooks when available (coming soon)

Error Handling

The API uses standard HTTP status codes:

Code Meaning Action
200 Success Continue
201 Created Resource created successfully
400 Bad Request Check your request parameters
401 Unauthorized Check your API token
403 Forbidden You don’t have permission
404 Not Found Resource doesn’t exist
422 Unprocessable Entity Validation failed
429 Too Many Requests Slow down, retry later
500 Server Error Contact support

Error responses include details:

{
  "error": "Validation failed",
  "details": {
    "name": ["can't be blank"],
    "start_date": ["must be in the future"]
  }
}

Use Cases

Here are some practical ways to use the API:

1. Automated Backups

Write a script that exports all your tour data as JSON and GeoJSON files:

#!/bin/bash
TOKEN="your_token_here"
curl -H "Authorization: Bearer $TOKEN" \
  https://a-grand-tour.com/api/v1/tours > tours_backup.json

Run this daily via cron to maintain backups.

2. Custom Integrations

Sync your tour data with other tools:

  • Import waypoints into a GPS device
  • Export expenses to accounting software
  • Push route updates to a team dashboard

3. Data Analysis

Extract data for custom analysis:

  • Calculate total distance across all tours
  • Analyze country visit patterns
  • Generate custom reports

4. Mobile App Development

The iOS companion app uses this same API. You could build:

  • An Android app
  • A command-line tool
  • A desktop application

5. Automation Scripts

  • Auto-generate documents from templates
  • Batch-import POIs from external sources
  • Sync with external calendar systems (beyond the built-in iCal feed)

Full API Documentation

Detailed documentation for every endpoint, including:

  • Request/response schemas
  • Authentication details
  • Pagination
  • Filtering and sorting
  • Webhooks (coming soon)

…is available at:

https://a-grand-tour.com/api/v1/docs

Visit that URL (with your API token) to browse the interactive API reference.

Managing API Tokens

Viewing Active Tokens

Go to Account SettingsAPI Tokens to see all your active tokens and when they were last used.

Revoking Tokens

If a token is compromised or no longer needed:

  1. Go to API Tokens
  2. Click Revoke next to the token
  3. Confirm

The token is immediately invalidated and will fail on next use.

Best Practices

  • Create separate tokens for different use cases (one for iOS app, one for scripts, etc.)
  • Revoke tokens you’re no longer using
  • Never commit tokens to version control
  • Use environment variables to store tokens in scripts
  • Regenerate tokens periodically for security

Support and Feedback

The API is actively developed. If you encounter issues, need help, or have feature requests:

  • Email: api-support@a-grand-tour.com
  • Documentation feedback: Use the “Report Issue” button in the API docs

We’re especially interested in hearing about:

  • Endpoints you wish existed
  • Performance issues
  • Integration challenges
  • Use cases we haven’t considered

Coming Soon

Planned API enhancements:

  • Webhooks: Get notified when data changes (instead of polling)
  • Batch operations: Update multiple items in one request
  • GraphQL endpoint: For more flexible queries
  • Real-time API: WebSocket support for live updates
  • OpenAPI spec: Auto-generate client libraries

Ready to start building? Head to Account SettingsAPI Tokens to generate your first token, then visit the API documentation for detailed endpoint references.