Skip to main content

Webform API reference

Submit enquiry

POST /webform/:tenantId/trip

Creates a Trip record in Salesforce from a webform submission.

Path parameters

ParameterRequiredDescription
tenantIdYesTenant slug (e.g. meridian). Used to resolve the per-tenant API key from the Edge vault and to load tenant-specific config (scoring, dedup, field mapping).

Headers

HeaderRequiredDescription
Content-TypeYesapplication/json
x-webform-keyYesPer-tenant API key, provisioned in the Edge vault under key webform_api_key
Idempotency-KeyRecommendedUUID to prevent duplicate processing on retry

Request body

{
"submissionId": "unique-id",
"submittedAt": "2026-06-26T10:00:00Z",
"originSite": "brand_uk",
"contact": {
"firstName": "Jane",
"lastName": "Smith",
"email": "jane@example.com",
"phone": "+44 7700 900000",
"bestTimeToCall": "Today 10:00",
"isTradeEnquiry": false
},
"trip": {
"readyToBook": "Yes",
"selectedTourTier": "Grand Tour of Switzerland",
"travelDate": "2027-05-14",
"groupSizeAdults": 2,
"travelFrom": "London"
}
}

Required fields

FieldTypeRequired
submissionIdstringYes
submittedAtISO 8601 stringYes
originSitestringYes
contact.firstNamestringYes
contact.lastNamestringYes
contact.emailvalid emailYes
trip.readyToBook or trip.bookingTimelinestringAt least one

All other fields are optional. The full schema is validated via Zod; invalid submissions receive a structured 400 response.

B2B fields (travel agent submissions)

FieldTypeDescription
contact.isTradeEnquirybooleanMarks the submission as a B2B agent enquiry
contact.travelAgencyNamestringAgency name (shown when isTradeEnquiry is true)
contact.agentAccreditationNumberstringIATA, CLIA, ABTA, or ASTA number — used to match to a Travel Agent Account in Salesforce

Success response (200)

{
"success": true,
"data": {
"submissionId": "unique-id",
"tripId": "a0A7Q000001234ABC",
"originSite": "brand_uk",
"createdAt": "2026-06-26T10:00:01Z",
"traceId": "abc-123-def",
"unmappedKeys": [],
"account": {
"accountId": "0017Q000001234ABC",
"accountName": "Jane Smith",
"matchedBy": "email"
},
"intelligence": {
"tier": "Standard",
"score": 60,
"queue": "standard",
"matchedRules": ["ready-to-book-today"]
}
},
"meta": {
"mode": "live",
"timestamp": "2026-06-26T10:00:01Z"
}
}

The intelligence object is only present when intelligence.enabled: true for the tenant.

Error responses

StatusError codeWhen
400VALIDATION_FAILEDMissing or invalid fields. details contains per-field errors.
401Invalid or missing API keyNo or invalid authentication header
409DUPLICATE_SUBMISSIONDedup rule matched with reject action. Response includes existingTripId.
500SALESFORCE_UPSTREAM_ERRORSalesforce returned an error during Trip creation

Idempotency

Include an Idempotency-Key header (UUID) to ensure safe retries. If the same key is sent twice, the second request returns 409 with the original submissionId.

Trip conversion

The Trip conversion guide is backed by two endpoints. They are an internal surface: the conversion canvas invokes them with a platform-internal credential, and they are not exposed for direct customer integration. The contracts are documented here so you can understand and verify what the panel does.

Record context

GET /api/v1/lead/context?tenantId={tenant}&sfEnvironment={env}&leadId={recordId}

Returns the normalized source record (name, company, email, phone, status, converted state), the enabled conversion paths, matched agency and customer candidates, and each candidate's open Trips (per the configured trip_candidates). Converted records return an empty candidate set.

Convert

POST /api/v1/lead/convert
Body fieldDescription
tenantId, sfEnvironment, leadIdTenant, Salesforce environment, and source record id
conversionPathbusiness_account or person_account (defaults to the configured default_path)
accountIdOptional. Convert against this existing Account instead of matching
contactIdOptional. Use this existing agent Contact (business path)
tripIdOptional. Attach to this existing Trip instead of creating one (requires accountId)
createNewAccountOptional. Force-create a new agency instead of matching (business path)

Success response:

{
"success": true,
"idempotent": false,
"path": "business_account",
"accountId": "001xx0000000000XXX",
"contactId": "003xx0000000000XXX",
"tripId": "a0Txx0000000000XXX",
"tripPath": "/lightning/r/KaptioTravel__Trip__c/a0Txx0000000000XXX/view",
"reusedExistingTrip": false,
"warnings": []
}

Conversion error semantics

StatusWhen
400Invalid record id, unknown path, or an incoherent request (e.g. attaching a Trip without selecting its account)
404Record or Trip not found — or the tenant has no enabled lead_to_trip configuration
409The selected Trip belongs to a different account than the conversion target. Nothing is mutated
422Salesforce rejected a record (validation rule, required field, missing person-account record type). The message is the org's own, surfaced verbatim to the agent

Converting an already-converted record is not an error: it returns idempotent: true with the existing ids. Non-blocking issues (e.g. a Trip stamp the org rejected) are returned in warnings.

Health check

GET /health

Returns service status, version, and available endpoints.