Skip to main content

Partner Management Features

Operational APIs used by authenticated partner organizations after onboarding.

1. Settings (/api/partner-settings)

  • GET /api/partner-settings
  • PATCH /api/partner-settings/profile
  • PATCH /api/partner-settings/business
  • PATCH /api/partner-settings/branding
  • POST /api/partner-settings/api-keys/regenerate
  • PATCH /api/partner-settings/api
  • PATCH /api/partner-settings/notifications
  • PATCH /api/partner-settings/billing
  • GET /api/partner-settings/commission
  • PATCH /api/partner-settings/commission
Commission rate is admin-controlled

PATCH /api/partner-settings/commission accepts customRates[] only (display JSON). Sending defaultRate / attempting to change seller_profiles.commissionRate is rejected (403 error.partner.commission_rate_admin_only when it reaches the service). Payout rate changes go through admin partners APIs.

API configuration webhook URL

PATCH /api/partner-settings/api with webhookUrl must be public HTTPS. Private/metadata URLs are rejected (same SSRF + pinned-DNS policy as portal webhooks).

2. Users (/api/partners/users)

  • POST /api/partners/users
  • GET /api/partners/users
  • GET /api/partners/users/statistics
  • GET /api/partners/users/:userId
  • PATCH /api/partners/users/:userId
  • DELETE /api/partners/users/:userId
  • POST /api/partners/users/invite
  • GET /api/partners/users/:userId/permissions
  • POST /api/partners/users/:userId/update-access
Invite is pending + manual email

POST /api/partners/users/invite creates a pending partner_user (isActive=false). It does not send email automatically (emailDelivery=pending_manual). Existing non-client system roles are rejected. New placeholder accounts stay on the client system role until accept.

3. Reports (/api/partner-reports)

  • GET /api/partner-reports/revenue
  • GET /api/partner-reports/performance
  • GET /api/partner-reports/top-destinations
  • GET /api/partner-reports/daily-revenue
  • GET /api/partner-reports/monthly-trend
  • GET /api/partner-reports/commission
  • GET /api/partner-reports/cenote-comparison

4. Reservations (/api/partner-reservations)

  • GET /api/partner-reservations
  • GET /api/partner-reservations/stats
  • GET /api/partner-reservations/:id
  • POST /api/partner-reservations
  • PATCH /api/partner-reservations/:id
  • POST /api/partner-reservations/:id/cancel
Create body is WEB-parity

POST /api/partner-reservations (and public POST /api/partner/reservations) accept the same core booking fields as WEB cenote create: ageBreakdown?, nationality?, transportationType?, pickup fields, additionalServices?, couponCode?, promotionId?, locale?, paymentMethod?, plus guest/contact contact fields. List filters honor dateFrom/dateTo and sortDirection aliases alongside startDate/endDate/sortOrder.

5. Webhooks (/api/partners/webhooks)

  • POST /api/partners/webhooks/test — partner JWT + permissions (partner.manage_settings); partner test endpoint
  • POST /api/partners/webhooks/triggerADMIN-only (@Roles(ADMIN)); distinct from the partner test endpoint above

Portal webhook CRUD lives under /api/partner-portal/webhooks* and enforces public HTTPS + no redirects + pinned DNS on outbound test/delivery.

6. Sandbox (/api/partner-sandbox) — live

info

Sandbox is live when schema partners_sandbox exists (migration v23.0.62+). Requires a sandbox sk_test_ API key. These keys are not valid on /api/partner/* production routes (sandbox_key_not_allowed_on_production_api). Generate counts are capped (max 50 per resource type).

  • POST /api/partner-sandbox/generate-data
  • GET /api/partner-sandbox/statistics
  • DELETE /api/partner-sandbox/cleanup

7. Webhook simulator (/api/partner/webhooks/simulator) — live

Requires sandbox sk_test_ key (same production-API restriction as §6).

  • POST /api/partner/webhooks/simulator/simulate
  • POST /api/partner/webhooks/simulator/simulate-batch
  • POST /api/partner/webhooks/simulator/test-endpoint
  • GET /api/partner/webhooks/simulator/history
Simulator bounds

delay ≤ 10s, batch size ≤ 20 events, history limit ≤ 500 (validated + server-clamped). Outbound posts use the same SSRF guard and pinned DNS (DNS is resolved after any delay).

8. Supply cenotes (/api/partner-portal/cenotes) — supply partners only

Eligible partner types: tour_operator and hotel_partner (active + verified). Demand-only types (OTA, travel agency, etc.) receive 403.

Requires JWT + partner roles (partner_admin / partner_manager) and permissions:

MethodPathPermission
GET/api/partner-portal/cenotespartner.view_cenotes
POST/api/partner-portal/cenotespartner.manage_cenotes
GET/api/partner-portal/cenotes/:idpartner.view_cenotes
PATCH/api/partner-portal/cenotes/:idpartner.manage_cenotes
POST/api/partner-portal/cenotes/:id/imagespartner.manage_cenotes
POST/api/partner-portal/cenotes/:id/request-publishpartner.request_publish_cenote
Workflow

draftrequest-publishpending_review → admin publish (active) or reject-publish (back to draft). Admin may suspend / reactivate. Partner may edit and attach images only while draft. Attach requires a file previously uploaded by the same user (uploaded_by).

Checklist before request-publish / admin publish: Spanish name, pricing (agePricing or packages), ≥1 active image.

Owned venue metrics: GET /api/partner-reports/owned-venues.

Notes

  • these routes are not part of the public API-key partner integration layer
  • most of them require JWT + partner context or additional permissions
  • reports and reservation statistics expose monetary values in cents at API contract level
  • POST /api/partner-settings/api-keys/regenerate once-reveals apiKey only (auth is JWT + partner roles/permissions; no functional x-api-secret); deactivate+insert runs in a DB transaction
  • Verified against partner-supply-cenotes (2026-08-04)