Post a traveler review on behalf of a completed booking
Creates a review tied to a Safariat booking that the partner itself created via
SafarAPI. The review is marked verified_booking=true by construction (any review
coming through this endpoint is anchored on a real, completed booking).
Constraints:
- The
booking_numbermust refer to a booking owned by the calling partner. - The booking status must be
COMPLETED. - At most one review per booking. A duplicate attempt returns
409 review.already.exists. commentminimum 10 characters;ratingbetween 1 and 5.
author_name is optional — when omitted, Safariat uses the lead traveler’s first name
from the booking contact information.
Requires scope reviews:write.
Authorizations
API key authentication. Issued by the Safariat admin or via the partner portal. The secret is shown only once at generation.
Production sk_live_* keys must additionally sign every write request
(POST/PUT/DELETE) with the X-Timestamp and X-Signature headers.
Sandbox sk_test_* keys are exempt from request signing: X-Signature and
X-Timestamp are not required for writes in the sandbox (so the developer-portal
"Try it" playground works end to end). The Idempotency-Key header remains
required on writes in both environments.
Headers
Opaque, client-generated string unique per logical operation (a UUID v4 is
recommended but any non-blank value up to 255 chars is accepted). Same key +
same body = the cached response is returned with the Idempotent-Replayed: true
header. Same key + different body = 409 Conflict. Retained for 24 h.
255Unix timestamp in seconds at the time the request is issued. Validity window
±5 minutes — beyond that the request is rejected. Required for production
sk_live_* keys only; not required for sandbox sk_test_* keys.
hex(HMAC_SHA256(secret, "{X-Timestamp}\n{METHOD}\n{path}\n{body}")).
The path includes the query string. The body is the exact JSON representation
sent — any reformatting invalidates the signature. Required for production
sk_live_* keys only; not required for sandbox sk_test_* keys.
^[a-f0-9]{64}$Body
Number of a completed booking owned by the calling partner.
^MV-[A-Z0-9]{6,}$"MV-20260714-AB7X92"
1 <= x <= 55
10 - 4000Optional short headline shown above the comment.
200Optional override for the displayed traveler name. When omitted, Safariat uses the lead traveler's first name captured at booking time.
200Up to 10 photo URLs previously issued by POST /files/presigned-upload for this partner. Each URL is verified server-side: any URL that does not scope to this partner's namespace or does not match an uploaded file returns 422 partner.review.photo.not.found.
10^https://Response
Review created
EXPERIENCE/TRIP:reviewable_idis the adventure id.AGENCY:reviewable_idis the agency id.
EXPERIENCE, TRIP, AGENCY 1 <= x <= 5Traveler display name as shown on the public Safariat site.
true when the review is tied to a confirmed Safariat booking.
x >= 0Up to 10 traveler-uploaded photos.