v1

Enrichment API

Send a raw DMC itinerary as plain text. Get back a fully structured, day-by-day travel proposal — with narratives, activity details, hotel, meals, transfers, and destination photos — ready to render in your app.

Quick start

One endpoint. Send your itinerary text, get a structured result. The call is synchronous — it holds the connection open and returns the full result when enrichment completes.

curl -X POST https://ai.supergryd.com/api/v1/enrich \
  -H "Authorization: Bearer live_sg_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Day 1: Arrive Ubud, check in to Alaya Resort. Spa treatment. Day 2: Tegalalang rice terrace, Tirta Empul temple...",
    "customer_nights": 5,
    "occasion": "Honeymoon",
    "budget": "premium",
    "pax_summary": "2 Adults"
  }'
Timeout: Set your HTTP client timeout to at least 300 seconds. Enrichment typically completes in 30–200 seconds depending on itinerary length and complexity. Shorter timeouts will abort a running enrichment and the call will still be charged.

Authentication

All requests require a bearer token in the Authorization header.

Authorization: Bearer live_sg_YOUR_API_KEY

Keep your key secret — it controls wallet spend. Contact your SuperGryd account manager to rotate or revoke.

POST /api/v1/enrich

Content-Type: application/json

Request body

FieldTypeDescription
text *stringRaw DMC itinerary text. 100–50,000 characters. Plain text, HTML, or copy-pasted from a document.
customer_nightsnumberNumber of nights the customer is travelling. 1–90. Default: 1. Used to compress or extend the DMC itinerary to match the booking.
occasionstringTrip purpose — shapes narrative tone. E.g. Honeymoon, Family Holiday, Adventure. Default: Leisure/Holiday.
budgetstringOne of budget, comfort, premium. Influences activity and hotel narrative. Default: comfort.
pax_summarystringPassenger description. E.g. 2 Adults, 1 Child (8). Used to generate relevant agent tips. Default: 2 Adults.
traveler_typesstring[]Optional traveler labels for personalised demographic tips. E.g. ["honeymooners","first-timers"].

Headers

HeaderDescription
Idempotency-KeyOptional. A unique string per request. If a completed job with the same key exists (within 24 hours), the cached result is returned without a new enrichment call or wallet deduction.

Response

HTTP 200. The response envelope has two top-level fields:

{
  "job_id": "93f465de-7844-4efd-aa96-49109990a3d4",
  "result": {
    "schema_version": "1.2",
    "destination": "Tokyo & Kyoto & Osaka",
    "duration_days": 8,
    "pax_summary": "2 Adults",
    "duration_action": "exact",
    "inclusions": ["Daily breakfast", "Airport transfers"],
    "exclusions": ["International flights", "Visa fees"],
    "transfers": ["Private transfer: Narita → Hotel (Day 1)"],
    "trip_maps_url": "https://www.google.com/maps/dir/Senso-ji+Temple+Tokyo/...",
    "city_heroes": {
      "tokyo": {
        "url": "https://images.unsplash.com/...",
        "photographer": "Louie Martinez",
        "photographerUrl": "https://unsplash.com/@louie..."
      }
    },
    "days": [ ... ]
  }
}

result fields

FieldTypeDescription
schema_versionstringSchema version of this response — e.g. 1.2. Use this to confirm which schema a response was generated against. Increments with every additive change. See the changelog for what changed per version.
destinationstringPrimary destination label derived from the itinerary.
duration_daysnumberNumber of days (nights + 1) in the enriched itinerary.
pax_summarystringPassenger description, echoed from the request or inferred.
duration_actionstringexact — DMC nights match. compress — DMC had more nights, merged to fit. extend — DMC had fewer nights, padded to fit.
inclusionsstring[]What's included in the package, extracted from the DMC text.
exclusionsstring[]What's not included, extracted from the DMC text.
transfersstring[]Transfer descriptions extracted from the DMC text.
city_heroesobjectMap of lowercase city name → { url, photographer, photographerUrl }. Sourced from Unsplash via destination_images cache. Use as day banner images. May be empty if Unsplash lookup fails.
trip_maps_urlstring | nullGoogle Maps directions URL covering all activity stops across every day of the trip. Null if fewer than 2 geocodable stops are found. Use this for a 'View full route on Google Maps' button.
daysM2Day[]Ordered array of day objects. See below.

M2Day

FieldTypeDescription
day_numbernumber1-based day index.
day_titlestringShort descriptive title for the day. E.g. "Arrival & Bamboo Groves".
citystringCity or location for this day.
hotelstring | nullHotel name extracted from DMC text, or null if not specified.
meals_includedstring[]Meals included from the hotel plan. E.g. ["Breakfast"].
day_introstring | nullContextual intro sentence — arrival/departure/intercity travel context. Null for standard days.
hotel_confidencestringConfidence level for the extracted hotel name: high, medium, or low.
day_metricsM2DayMetricsFatigue and occasion scores for the day. See below.
day_maps_urlstring | nullGoogle Maps directions URL for this day's activity stops only. Null if fewer than 1 geocodable stop is found. Use this for a 'View Day N on Google Maps' button.
slotsItinerarySlot[]Ordered activities, meals, and transfers for this day.

M2DayMetrics

FieldTypeDescription
fatigue_scorenumber1–10 score indicating physical intensity of the day's activities.
occasion_scorenumber1–10 score indicating how well the day suits the trip occasion (e.g. Honeymoon, Family).

ItinerarySlot

FieldTypeDescription
slot_indexnumber0-based position of this slot within the day.
slot_typestringOne of activity, meal, transfer, rest.
titlestringShort slot title.
narrativestring2–3 sentence description for activities, 1 sentence for meal/transfer slots.
time_hintstring | nullLoose time-of-day grouping: morning, afternoon, evening. Display hint only — not structural.
duration_minsnumber | nullEstimated duration in minutes. Null if not determinable.
maps_linkstring | nullGoogle Maps search URL. Format: https://www.google.com/maps/search/?api=1&query=PLACE+CITY. Present on activity and meal slots.
dining_linkstring | nullGoogle Maps dining search URL. Present on meal slots only.
nearby_linkstring | nullGoogle Maps "things to do" search URL for the day's city.
demographic_catering_notestring | nullAgent-facing tip tailored to the traveler profile (pax_summary / traveler_types). Shown as an amber tip box.
sourcestringOrigin of this slot: dmc = extracted directly from DMC text, ai_fill = AI-generated to fill the day, agent_custom = manually added by a SuperGryd agent.
is_mandatorybooleanTrue if this slot has been locked by a SuperGryd agent and cannot be removed.
image_urlstring | nullAuto-assigned Unsplash photo for this slot. Use this as the slot image when media[] is empty.
mediaSlotMedia[]Array of photos, YouTube videos, or links. Empty for freshly generated itineraries — API partners can populate this before rendering to add their own rich media.

SlotMedia

FieldTypeDescription
typestringOne of photo, youtube, link.
urlstringPhoto: image URL. YouTube: bare video ID. Link: full URL.
thumbnail_urlstring?YouTube only: thumbnail URL.
titlestring?YouTube: video title. Link: page title.
altstring?Photo only: accessibility label for the image.
favicon_urlstring?Link only: favicon URL for the linked domain.
og_imagestring?Link only: og:image URL for a richer link preview.
descriptionstring?Link only: og:description or meta description of the linked page.
Schema stability: The response schema is stable within v1. New optional fields may be added without a version bump — build your parser to ignore unknown fields.

Error codes

All errors return { "error": { "code": "...", "message": "..." } } except auth errors which return { "error": "...", "message": "..." } (flat, no nesting).

CodeHTTPDescription
missing_key401Authorization header missing or empty.
invalid_key401API key not found or invalid.
key_not_found401API key does not exist.
key_inactive403API key has been revoked.
invalid_body400Request body is not valid JSON.
input_too_short422text is under 100 characters.
input_too_long422text exceeds 50,000 characters.
invalid_nights422customer_nights is outside 1–90.
rejected_non_leisure422Input was rejected — not a leisure itinerary (e.g. MICE, flights-only).
parse_failed422Could not extract a structured itinerary from the text.
insufficient_balance402Wallet balance too low to process a call.
wallet_suspended403Wallet has been suspended. Contact your account manager.
no_wallet500Wallet record not found for this API key. Contact your account manager.
enrichment_failed500AI enrichment failed. Resubmit your request.
internal_error500Unexpected server error.

Billing

The API uses a prepaid wallet. Each enrichment call deducts from your wallet at submission. Calls rejected before reaching enrichment — auth errors, validation errors, insufficient balance — are not charged.

Check your usage at any time:

curl https://ai.supergryd.com/api/v1/keys \
  -H "Authorization: Bearer live_sg_YOUR_KEY"

To top up your wallet or discuss pricing, contact your SuperGryd account manager.

See what the output looks like

Three rendered examples — Bali, Maldives, Japan — using real API responses.

View sample output →

Schema stability

The API is v1. Changes within v1 are additive only. Build your parser to ignore unknown fields. Breaking changes increment to v2 with advance notice.

View changelog →