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
- Go to Account Settings → API Tokens
- Click Generate New Token
- Give it a descriptive name (e.g., “Backup Script”, “iOS App”)
- Click Create
- 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 Settings → API Tokens to see all your active tokens and when they were last used.
Revoking Tokens
If a token is compromised or no longer needed:
- Go to API Tokens
- Click Revoke next to the token
- 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 Settings → API Tokens to generate your first token, then visit the API documentation for detailed endpoint references.