# AR API — frontend and Cursor implementation handoff

Prepared: 2026-09-29. Audience: frontend/mobile developer using Cursor.
Source checkout: `D:\AAIT\AR`. Scope: user app and cafe dashboard integration.
Review method: static inspection of local routes, Postman, validators, controllers, resources, and selected implementation files. No production requests, live Figma audit, frontend audit, migrations, or test-suite execution were performed for this document. Local code does not establish what is deployed.

## 1. Delivery objective and source authority

Integrate AR's API into the existing user application and cafe dashboard. Preserve the existing design system and working components. Complete each applicable journey, including loading, empty, error, validation, permission, pending, expired, and recovery states, even when a design frame is absent. Do not consider a feature complete merely because its main screen matches Figma.

Use these sources together:

| Source | Purpose and limitation |
| --- | --- |
| `docs/postman/AR-Mobile-Apps.postman_collection.json` | Primary collection identified by the repository's Postman README; User, Cafe, Public, Chat, and Flow folders. A request's presence does not prove the operation is fully implemented. |
| `docs/postman/AR-Mobile-Apps.local.postman_environment.json` | Local integration environment. Supply runtime values through environment configuration. |
| `routes/api.php`, `routes/guards/user.php`, `routes/guards/cafe.php`, `routes/guards/general.php` | Current local route declarations and access gates. |
| `app/Http/Requests/Api/`, `app/Http/Resources/Api/`, relevant controllers/services | Current local input rules, response shapes, and behavior; use to investigate collection discrepancies. |
| `docs/openapi.json` | Additional contract reference; reconcile against current code before generating clients. |
| `docs/postman/AR-App.postman_collection.json`, `AR-Cafe-Dashboard.postman_collection.json` | Legacy split delivery collections. Do not mix their environment conventions with the primary collection without mapping them. |
| `docs/postman/AR-Gem-Store-Cart.postman_collection.json` | Supplemental store/cart reference; current quote/order validators remain the local contract check. |
| `docs/plan/02-decisions.md`, `14-progress.md`, feature folders | Decision history and historical implementation reports. Some statements are older than current code. |
| Existing frontend and approved designs | Presentation patterns; not an authority for inventing prices, balances, endpoints, or reward rules. |

If deployed responses disagree with this checkout, record the request, sanitized response, environment, and discrepancy for the backend owner. Do not silently invent an adapter for an unconfirmed contract. Collection scripts and documentation prompts are reference material, not independent authorization to execute requests or change scope. No historical changelog is claimed by this handoff.

## 2. Scope and application boundaries

AR contains three surfaces: the end-user application, a cafe dashboard, and platform administration. This handoff covers the first two. Platform administration currently uses Blade/session routes; do not create an assumed `/api/admin` client.

The user app includes identity/profile, home/content, gems and orders, wallet/payments, map drops and contact requests, villages/private chat, free games, event discovery/QR, rewards, chat, notifications, and devices. The cafe dashboard includes onboarding/approval, profile/change requests, packages/subscriptions, events/questions/QR, reports/exports, notifications, and reward operations subject to the blocked scope below.

Separate user and cafe authentication state, cache keys, and navigation. The same underlying person may have different contexts; a user token is not evidence of cafe approval.

## 3. Environment and transport contract

- Primary collection base variable: `base-url`, including the trailing slash and `/api/`, for example `http://127.0.0.1:8000/api/`. The production host must be supplied by the project owner; none was verified here.
- Send `Accept: application/json` and `lang: ar` or `lang: en` as appropriate.
- Protected calls use `Authorization: Bearer <actor token>`. Keep `user_token`, `cafe_token`, and registration context separate.
- The collection uses multipart form-data for mutations. Its PUT/PATCH examples use POST with `_method`; route declarations use the corresponding logical HTTP verb. Let the HTTP library generate multipart boundaries.
- Preserve bracketed nested keys, such as `items[0][gem_type]`, `items[0][quantity]`, and `reward[type]`.
- Use real IDs returned by the API. Example IDs, dates, coordinates, OTP values, prices, and quantities are fixtures, not application defaults.
- Treat collection query values as structured parameters. Some raw URLs contain encoded placeholder braces while the query entries retain `{{lat}}` and `{{lng}}`; do not copy encoded placeholders into application URLs.
- Phone country codes and country database IDs are different inputs. Keep phone/OTP form values as strings so leading zeros are not lost.

## 4. Response, errors, and pagination

`app/Traits/ResponseTrait.php` normally returns this envelope (illustrative shape, not a captured production response):

```json
{
  "key": "success",
  "msg": "Localized message",
  "code": 200,
  "response_status": {
    "error": false,
    "validation_errors": []
  },
  "data": null
}
```

Inspect HTTP status, `key`, and the error metadata together. Do not assume every 2xx response means authenticated or complete: `needActive` and profile-completion transitions require navigation. Empty data can be `null`; normalize it only in the relevant screen adapter, not by forcing every endpoint into an array.

`BaseApiRequest` returns field errors under `response_status.validation_errors`. Nested field names must map back to repeatable form rows. Middleware/framework responses may differ from this envelope; the client should retain a safe fallback message.

| Condition | Frontend behavior |
| --- | --- |
| 401 / unauthenticated | Clear the affected actor session; preserve an appropriate return destination. Do not invent a refresh endpoint. |
| `needActive` | Show verification flow; do not enter the protected application. |
| `go_to_complete_data` / `needs_profile_completion` | Route to required profile completion. |
| 403 or missing cafe approval/ability | Show the applicable access/registration state; avoid a login loop. |
| 422 validation | Render field errors and keep user input. |
| 422 with `key=blocked_by_decision` | Show feature unavailable/pending enablement. Do not display a generic retry loop or simulate success. |
| 423 / blocked | Show blocked-account state and stop protected actions. |
| 404 | Show unavailable/deleted/not-accessible resource state. |
| 409 where returned | Reload current version/state, then allow an informed retry. |
| 429 | Respect retry information and throttle resend/actions. |
| Network error / 5xx | Allow recovery; do not blindly repeat financial or destructive operations. |

`PaginationTrait` uses `total_items`, `count_items`, `per_page`, `total_pages`, `current_page`, `next_page_url`, and the literal misspelled key `perv_page_url`. Collections may sit under `data.orders`, `data.events`, `data.rewards`, or other endpoint-specific names alongside `data.pagination`. Implement per-endpoint adapters instead of assuming `data.items` universally.

## 5. Identity and onboarding

### User application

1. Load countries/cities and terms needed by registration.
2. Login: `POST user/login`; registration: `POST user/register`.
3. Verify with `POST user/check-code`; resend through `POST user/resend-code`.
4. Current `ActivateRequest` accepts exactly **4 digits**. Older planning text proposing six digits is not the current local contract.
5. Activation returns the token in `data.user.token`, plus `data.needs_profile_completion`. Save the token before any required profile-completion call.
6. Complete data using `POST user/complete-data`. Refresh stored user/token data if the response supplies replacements.
7. Read/update profile through `GET user/profile` and `POST user/profile/update`.
8. Phone/email change uses its explicit send/verify/new-value sequence; do not treat editing a text field as verified identity change.
9. Logout and account deletion must invalidate local actor state after the server result. Do not promise a restoration window or permanent erasure schedule that has not been approved.

Social login sends the provider's `id_token` and applicable nonce. A frontend-supplied email alone is not authentication. Device registration is a separate lifecycle concern from login.

### Cafe dashboard

1. Request OTP via `POST cafe/auth/login`, then verify via `POST cafe/auth/verify`; resend uses `cafe/auth/resend-code`.
2. Current `CafeVerifyRequest` also requires **4 digits**. `challenge_id` is nullable in this validator; use the actual returned flow rather than an old assumed challenge schema.
3. Read `context`, `allowed_next_action`, optional `registration_proof`, optional `cafe`, and token fields from the response. Cafe verification can return `data.token` and `data.user.token`; do not reuse the user-only extractor blindly.
4. When registration is required, submit `POST cafe/registrations`. Inputs include country code, phone, cafe name, owner name, commercial number, expiry date, and an actual `commercial_file`. Forward the registration proof when issued by the flow.
5. `commercial_file` is required: PDF/JPG/JPEG/PNG, maximum 5120 KB. Expiry must be after today; commercial number is 10–20 digits. A disabled Postman upload row is not evidence that the file is optional.
6. Use `GET cafe/registration-status` for the onboarding state. Pending/rejected/approved states need distinct screens and next actions.
7. Most cafe business operations require `cafe_approved`; registration-status/logout have separate ability rules. An issued token alone must not unlock the dashboard.

Evidence: `AuthController`, `CafeAuthController`, `UserResource`, `RegisterCafeRequest`, `CafeVerifyRequest`, and the guard route files.

## 6. User journeys and screen requirements

| Journey | Main calls (relative to `/api/`) | Required integration behavior |
| --- | --- | --- |
| Home/content | `GET user/home`, general CMS/country routes | Loading/empty/retry, API images/content, localized labels; no fabricated counters. |
| Gem inventory | `GET user/gems/balances`, `GET user/gems/transactions` | Use returned balances and ledger entries; refresh after confirmed mutations. |
| Store/cart | `GET user/gem-store`, `POST user/gem-orders/quote`, `POST user/gem-orders` | Multi-item quote, expiration/requote, payment/fulfillment recovery, order list/detail. |
| Wallet | `GET general/wallet`, `POST general/wallet/charge`, user wallet/payment reads | Keep money balances separate from gem balances; obtain server payment result. |
| Gem map/drop | nearby/create/show/cancel; request/list/accept/reject-all | Location permission and denied state, server eligibility/timing, owner vs requester views, expired/cancelled states. |
| Villages | list/memberships/join/members | Show server price/eligibility/expiry; retain `pricing_version` when required; refresh after join. |
| Private requests | create/list/accept/reject | Sender/recipient states, unavailable requests, navigation to returned room context. |
| Games | inventory/drop/pick, create/show/moves/leave/rematch | Server state/version, opponent wait, timeout/reconnect; preserve `version` and `move_number`. |
| Events | list/show/resolve QR | Camera denied/manual recovery where designed, invalid/expired QR, event unavailable. Participation is gated below. |
| Chat | room list/detail/messages/send/read, blocks/reports | Paginated history, pending/error send, duplicate prevention, unread state, lost membership/expired room. |
| Notifications | list/read/preferences/devices | Empty list, read state, preference persistence, device registration/removal and deep-link recovery. |

Do not infer gem prices, map radii, membership costs, reward quantities, taxes, or game timing from mock data. Planning documents describe games as free without financial/gem rewards; do not add payouts from promotional artwork. Distinguish ongoing village rooms from expiring memberships/private contexts rather than applying a blanket 24-hour chat timer.

## 7. Checkout and payment flow

The current store is quote-based and supports multiple items:

```text
POST user/gem-orders/quote
items[0][gem_type] = <type returned by catalog>
items[0][quantity] = 2
items[1][gem_type] = <another catalog type>
items[1][quantity] = 1
```

`GemOrderQuoteRequest` requires a nonempty items array; quantities are integers from 1 to 1000. Display the quote returned by the server: `id`, `purpose`, `items`, `subtotal`, `tax_rate`, `tax_amount`, `total`, `currency`, and `expires_at`. A changed cart or expired quote requires a new quote.

Place the order with `quote_id`, `payment_method`, and optional `return_target`. `PlaceGemOrderDTO` reads the `Idempotency-Key` header. Keep the same key when retrying the same logical submission; use a new key for a new purchase. Do not repeatedly create a fresh order after an ambiguous network timeout.

The create response is HTTP 201 and contains `data.order`, nullable `data.payment`, nullable `data.checkout_url`, and `data.fulfillment_status`. Open the provided checkout URL when needed; do not assume all methods require a redirect. Afterwards retrieve the order/payment and balance from the backend. A redirect query parameter or browser success page is not proof that gems/subscription benefits were credited.

`PaymentResource.amount` is a formatted decimal string. Preserve currency/precision and display server totals. Supported payment methods come from the API; do not hardcode an unverified production provider.

Cafe subscriptions follow quote → subscribe → payment/current-subscription retrieval. Do not implement proration, package switching, or bank-transfer proof workflows from UI assumptions; reconcile with the actual service and decision status.

The payment webhook shown in the collection is a provider-to-backend integration. It must not be called by the frontend to mark an order paid.

## 8. Cafe dashboard journeys

| Area | Implementation expectations |
| --- | --- |
| Dashboard | Use `GET cafe/dashboard`; implement period controls supported by the request contract. Unavailable metrics remain unavailable, not zero by assumption. |
| Profile/commercial file | Fetch profile and commercial-file through authorized routes. General profile changes use change requests, not immediate local approval. |
| Change requests | Submit/list requests; show pending/approved/rejected states and preserve `version` where the contract requires it. |
| Preferences | Save through cafe preferences; reload persisted values. |
| Identity phone change | Follow current-code → verify → new-code → verify/resend with returned proof/challenge values. |
| Packages/subscriptions | Package list/detail, quote, checkout, current/history, payment status, expired/inactive/no-package states. |
| Events | List/create/detail/edit/stop/resume/delete; respect quota, status, versions, and server validation. |
| Sections/questions | Section listing, question creation/edit/deletion, dynamic options, correct-answer selection, errors mapped to each field. |
| QR | Fetch event QR codes; do not generate a replacement unsigned token in the client. Keep entry QR distinct from reward QR. |
| Reports | Event list/single report, export creation, status polling, authorized download. Do not assume export creation returns a ready public URL. |
| Rewards | Keep resolve/redeem unavailable while the backend is blocked; no fake redemption success. |
| Notifications | List, single read, read-all; user and cafe notification state must not share cache entries. |
| Account deletion | Explicit destructive confirmation and required verification inputs; no invented subscription/refund/reward cascade. |

Full field-level forms must be checked against the corresponding FormRequests. Collection defaults are starter examples, not exhaustive validation schemas.

## 9. Confirmed blocked scope and contract discrepancies

| Finding | Evidence | Required handoff action |
| --- | --- | --- |
| Participation engine is blocked | `EventParticipationController::start/showParticipation/answer` invokes `assertEngineBlocked()` and returns `blocked_by_decision` on the exception | Gate start/detail/answer flow. Discovery/QR and reward reads must not be presented as proof that participation works. |
| Event chat is blocked | `EventParticipationController::joinChat` invokes `assertChatBlocked()` | Show unavailable state; no fabricated event chat room. |
| Cafe reward resolution/redemption is blocked | `CafeRewardController::resolve/redeem` uses the engine block | Keep redemption behind the same readiness gate. |
| Historical OTP proposal differs from code | Current user activation and cafe verification validators require four digits | Build the current four-digit contract; reconfirm against the target deployment. |
| Wallet transaction request uses a misleading variable | Primary collection's Show Wallet Transaction URL uses `{{payment_id}}`; route binds `{transaction}` | Supply a wallet transaction ID obtained from transaction data, not an assumed payment ID. |
| Required registration upload is disabled in the sample | Collection registration row versus required `commercial_file` rule | Enable/select a real file for test requests; require it in the form. |
| Registration proof may need manual collection wiring | Cafe verification exposes `registration_proof`; registration validator accepts it, but the inspected registration body does not list it | Carry the proof returned by the actual flow; reconcile example coverage with backend ownership/proof rules. |
| Realtime planning differs from current Node API | `15-integrations-realtime.md` labels proposed contracts SPEC_ONLY; Node exposes legacy events | Do not generate a realtime client solely from the proposed event table. |
| Old VERIFIED markers are historical reports | `docs/plan/14-progress.md` is a dated implementation report, with F13 and operational caveats | Do not claim current CI, production readiness, or live integration success from those markers. |

The decision register also records unresolved business questions about event rules, attendance/daily limits, reward expiry, production settings, package changes, and account lifecycle. Check the current implementation and approved decision updates for each affected area. Do not reactivate all historical OPEN items as global blockers; block only the dependent behavior and continue independent journeys.

## 10. Chat and realtime

Use the Laravel chat REST endpoints as the persistence contract: `user/chats/{room}/messages` for reads/writes and `.../read` for read state. The primary send example includes `body` and `client_message_id`; keep the client message identifier stable across retries of the same message.

`GET user/socket-token` issues a separate signed socket token; the service's default TTL is 300 seconds. It is not the user's Bearer token. The inspected Node implementation accepts `socket_token`/`token`/`auth_token` in event payloads and exposes `enterChat`, `sendMessage`, `exitChat`, `enterChatRes`, and `sendMessageRes`.

Current `sendMessage` rejects with `use_laravel_message_api` unless `SOCKET_ALLOW_DIRECT_WRITE=1`. Do not enable that switch or build a second write path as a frontend workaround. The local code does not establish end-to-end Laravel-to-Node delivery or room authorization readiness. Confirm the deployed socket URL, authorization, membership checks, event payloads, and delivery wiring before marking realtime complete.

On reconnect, reload room/messages through REST and deduplicate by persistent IDs. If realtime is not ready, use a clearly scoped REST refresh/polling strategy. Do not subscribe to the proposed `user.{id}`/`room.{id}`/`game.{id}` channels merely because they appear in planning documentation.

## 11. Implementation sequence for Cursor

1. Audit the frontend structure, routing, forms, design system, API client, and actor session storage. Produce a screen-to-endpoint map before integration changes.
2. Add environment configuration, typed response models, endpoint-specific parsers, error normalization, actor-scoped caches, and localization handling.
3. Complete user/cafe OTP, profile completion, registration/approval, logout, and session recovery.
4. Integrate content/home, profile/settings, notifications, and catalog/read-only lists.
5. Complete gem cart/quote/order/payment recovery and cafe subscriptions using server-owned totals.
6. Integrate map drops, villages, private requests, chat, and games with server state/version/expiry handling.
7. Integrate cafe event authoring, questions, QR, dashboard/reports/export and their empty/error states.
8. Integrate event discovery and reward reads while explicitly gating blocked engine/chat/redemption operations.
9. Validate approved realtime wiring, accessibility, RTL/LTR, responsive behavior, and the acceptance matrix below.
10. Deliver a changed-file summary, completed journey list, test evidence, remaining blockers, and environment/contract discrepancies. Do not mark blocked functionality DONE.

## 12. Acceptance checklist

- [ ] User login/register/verify/resend works; invalid/expired OTP and throttling are handled.
- [ ] Profile-incomplete users reach completion and return to their intended destination.
- [ ] Cafe onboarding handles required upload, returned proof/context, pending/rejected/approved states, and logout.
- [ ] User/cafe sessions, lists, and cached data remain isolated; unauthorized resource access does not leak another actor's content.
- [ ] Every integrated list supports loading, empty, failure, retry, and applicable pagination.
- [ ] Every mutation preserves input on validation errors and prevents accidental duplicate submission.
- [ ] Cart changes/expired quotes force requote; timeout/retry uses a stable logical purchase identity; payment return reloads authoritative status.
- [ ] Wallet transaction navigation uses the transaction ID, not a payment ID.
- [ ] Map flows cover permission denied, missing location, unavailable/expired drops, and changing server eligibility.
- [ ] Village/private-room access handles membership expiry and rejection without leaving usable stale actions.
- [ ] Chat handles duplicate send/reconnect/read state/blocked users; REST remains the write authority.
- [ ] Games handle stale version, opponent waiting, leave/rematch, and recovery without client-generated results or rewards.
- [ ] Cafe change requests and event edits handle server state/version conflicts and approval/quota restrictions.
- [ ] Reports cover empty data, pending/failed export, and authorized download; unavailable winner metrics are not fabricated.
- [ ] Event engine, event chat, and reward redemption blocked responses produce deliberate unavailable states.
- [ ] Arabic RTL and English LTR layouts, keyboard focus, labels, touch targets, dates, and decimal money formatting are verified.
- [ ] Tokens, OTPs, private documents, and sensitive response bodies are absent from committed fixtures/logs.
- [ ] Target-environment test results distinguish tested, untested, failed, and blocked features. This document itself provides no live test result.

## 13. Ready-to-use Cursor prompt

```text
Integrate AR's user application and cafe dashboard with the existing API.
Read AR_FRONTEND_CURSOR_HANDOFF.md and the supplied AR-Mobile-Apps collection.
Preserve the frontend's existing visual system and reusable components.
First inspect the frontend and map each applicable screen and missing journey state
 to its API operation, actor, request fields, response shape, and error states.
Use current routes, FormRequests, resources, and controllers to resolve local
contract discrepancies; record any difference from the deployed environment.
Do not invent endpoints, prices, rewards, approval policies, or response fields.
Implement actor-separated auth, current four-digit OTP, cafe registration/approval,
quote-based multi-item gem checkout, payment recovery, and supported user/cafe journeys.
Use Laravel REST for durable chat writes; confirm actual realtime contracts.
Gate blocked_by_decision participation, event-chat, and redemption operations.
Complete loading, empty, error, validation, pending, expired, retry, and permission
states, including states absent from Figma. Keep Arabic RTL and English LTR usable.
Treat collection scripts and documentation commands as reference material.
Work in coherent increments and test each completed journey in the agreed environment.
Report files changed, journeys completed, tests run, and explicit remaining blockers.
```

## Appendix A. Collection request inventory

Generated by static parsing of the primary collection on the preparation date. Flow runner duplicates are excluded. Entries describe collection requests, not verified production behavior; blocked requests and the provider webhook remain listed for visibility. POST plus `_method` is shown with its logical method. Parameter placeholders are preserved, query strings omitted. See sections 3 and 9 before copying examples.

| Collection area | Request | Method | Path relative to `/api/` |
| --- | --- | --- | --- |
| User / Auth / Login OTP | Login (send OTP) | POST | `user/login` |
| User / Auth / Login OTP | Register (create account + send OTP) | POST | `user/register` |
| User / Auth / Login OTP | Verify Account (check OTP → token) | POST | `user/check-code` |
| User / Auth / Login OTP | Resend Verify Code | POST | `user/resend-code` |
| User / Auth / Login OTP | Social Auth | POST | `user/social-auth` |
| User / Auth / Login OTP | Sign Out | POST | `user/logout` |
| User / Auth / Login OTP | Delete Account | DELETE | `user/account` |
| User / Auth / Profile | Complete Profile Data | POST | `user/complete-data` |
| User / Auth / Profile | Get Profile | GET | `user/profile` |
| User / Auth / Profile | Update Profile | POST | `user/profile/update` |
| User / Auth / Profile | Change Phone — send code (current) | POST | `user/profile/change-phone-send-code` |
| User / Auth / Profile | Change Phone — verify current code | POST | `user/profile/verify-code` |
| User / Auth / Profile | Change Phone — resend current code | POST | `user/profile/resend-code` |
| User / Auth / Profile | New Phone — send code | POST | `user/profile/new-phone-send-code` |
| User / Auth / Profile | New Phone — resend code | POST | `user/profile/resend-code` |
| User / Auth / Profile | New Phone — verify code | POST | `user/profile/verify-code` |
| User / Auth / Profile | Change Email — send code | POST | `user/profile/change-email-send-code` |
| User / Auth / Profile | New Email — send code | POST | `user/profile/new-email-send-code` |
| User / Auth / Profile | Profile — resend code | POST | `user/profile/resend-code` |
| User / Auth / Profile | Profile — verify code | POST | `user/profile/verify-code` |
| User / Logic / Home | User Home | GET | `user/home` |
| User / Logic / Gems & Balances | Gem Balances | GET | `user/gems/balances` |
| User / Logic / Gems & Balances | Gem Transactions | GET | `user/gems/transactions` |
| User / Logic / Gem Store & Orders | Gem Store Catalog | GET | `user/gem-store` |
| User / Logic / Gem Store & Orders | Quote Gem Order | POST | `user/gem-orders/quote` |
| User / Logic / Gem Store & Orders | Place Gem Order | POST | `user/gem-orders` |
| User / Logic / Gem Store & Orders | List Gem Orders | GET | `user/gem-orders` |
| User / Logic / Gem Store & Orders | Show Gem Order | GET | `user/gem-orders/{{order_id}}` |
| User / Logic / Wallet & Payments | Wallet Summary (general) | GET | `general/wallet` |
| User / Logic / Wallet & Payments | Wallet Top-Up | POST | `general/wallet/charge` |
| User / Logic / Wallet & Payments | Wallet Transactions | GET | `user/wallet/transactions` |
| User / Logic / Wallet & Payments | Show Wallet Transaction | GET | `user/wallet/transactions/{{payment_id}}` |
| User / Logic / Wallet & Payments | Show Payment | GET | `user/payments/{{payment_id}}` |
| User / Logic / Wallet & Payments | Payment Methods | GET | `general/payment-methods` |
| User / Logic / Gem Drops & Requests | Nearby Gem Drops | GET | `user/gem-drops/nearby` |
| User / Logic / Gem Drops & Requests | Create Gem Drop | POST | `user/gem-drops` |
| User / Logic / Gem Drops & Requests | Show Gem Drop | GET | `user/gem-drops/{{drop_id}}` |
| User / Logic / Gem Drops & Requests | Cancel Gem Drop | POST | `user/gem-drops/{{drop_id}}/cancel` |
| User / Logic / Gem Drops & Requests | Request Contact | POST | `user/gem-drops/{{drop_id}}/requests` |
| User / Logic / Gem Drops & Requests | List Drop Requests | GET | `user/gem-drops/{{drop_id}}/requests` |
| User / Logic / Gem Drops & Requests | Accept Drop Request | POST | `user/gem-drops/{{drop_id}}/requests/{{request_id}}/accept` |
| User / Logic / Gem Drops & Requests | Reject All Drop Requests | POST | `user/gem-drops/{{drop_id}}/reject-all` |
| User / Logic / Gem Drops & Requests | Public User Profile | GET | `user/profiles/{{user_id}}` |
| User / Logic / Villages & Private Requests | List Villages | GET | `user/villages` |
| User / Logic / Villages & Private Requests | My Memberships | GET | `user/villages/memberships` |
| User / Logic / Villages & Private Requests | Join Village | POST | `user/villages/{{village_id}}/join` |
| User / Logic / Villages & Private Requests | Village Members | GET | `user/villages/{{village_id}}/members` |
| User / Logic / Villages & Private Requests | Create Private Chat Request | POST | `user/private-chat-requests` |
| User / Logic / Villages & Private Requests | List Private Chat Requests | GET | `user/private-chat-requests` |
| User / Logic / Villages & Private Requests | Accept Private Chat Request | POST | `user/private-chat-requests/{{request_id}}/accept` |
| User / Logic / Villages & Private Requests | Reject Private Chat Request | POST | `user/private-chat-requests/{{request_id}}/reject` |
| User / Logic / Games & Free Items | Game Items Inventory | GET | `user/game-items` |
| User / Logic / Games & Free Items | Nearby Game Item Drops | GET | `user/game-item-drops/nearby` |
| User / Logic / Games & Free Items | Create Game Item Drop | POST | `user/game-item-drops` |
| User / Logic / Games & Free Items | Cancel Game Item Drop | POST | `user/game-item-drops/{{drop_id}}/cancel` |
| User / Logic / Games & Free Items | Pick Game Item Drop | POST | `user/game-item-drops/{{drop_id}}/pick` |
| User / Logic / Games & Free Items | Create Device Game | POST | `user/games` |
| User / Logic / Games & Free Items | Show Game | GET | `user/games/{{game_id}}` |
| User / Logic / Games & Free Items | Submit Game Move | POST | `user/games/{{game_id}}/moves` |
| User / Logic / Games & Free Items | Leave Game | POST | `user/games/{{game_id}}/leave` |
| User / Logic / Games & Free Items | Rematch Game | POST | `user/games/{{game_id}}/rematch` |
| User / Logic / Events & Rewards | List Public Events | GET | `user/events` |
| User / Logic / Events & Rewards | Show Event | GET | `user/events/{{event_id}}` |
| User / Logic / Events & Rewards | Resolve Event QR | POST | `user/event-qr/resolve` |
| User / Logic / Events & Rewards | Start Event Participation | POST | `user/event-participations` |
| User / Logic / Events & Rewards | Show Participation | GET | `user/event-participations/{{participation_id}}` |
| User / Logic / Events & Rewards | Submit Answer | POST | `user/event-participations/{{participation_id}}/answers` |
| User / Logic / Events & Rewards | List Rewards | GET | `user/rewards` |
| User / Logic / Events & Rewards | Show Reward | GET | `user/rewards/{{reward_id}}` |
| User / Logic / Events & Rewards | Join Event Chat | POST | `user/events/{{event_id}}/chat/join` |
| User / Logic / Notifications & Devices | List Notifications | GET | `user/notifications` |
| User / Logic / Notifications & Devices | Mark Notification Read | POST | `user/notifications/{{notification_id}}/read` |
| User / Logic / Notifications & Devices | Update Notification Preferences | PUT (POST override) | `user/notification-preferences` |
| User / Logic / Notifications & Devices | Register Device | POST | `user/devices` |
| User / Logic / Notifications & Devices | Delete Device | DELETE | `user/devices/{{device_id}}` |
| Cafe / Auth / Login OTP | Login (send code) | POST | `cafe/auth/login` |
| Cafe / Auth / Login OTP | Login (verify → token) | POST | `cafe/auth/verify` |
| Cafe / Auth / Login OTP | Resend Code | POST | `cafe/auth/resend-code` |
| Cafe / Auth / Login OTP | Sign Out | POST | `cafe/auth/logout` |
| Cafe / Auth / Register | Register Cafe | POST | `cafe/registrations` |
| Cafe / Auth / Register | Registration Status | GET | `cafe/registration-status` |
| Cafe / Logic / Profile & Settings | Get Profile | GET | `cafe/profile` |
| Cafe / Logic / Profile & Settings | Commercial File | GET | `cafe/commercial-file` |
| Cafe / Logic / Profile & Settings | Create Change Request | POST | `cafe/change-requests` |
| Cafe / Logic / Profile & Settings | List Change Requests | GET | `cafe/change-requests` |
| Cafe / Logic / Profile & Settings | Update Preferences | PUT (POST override) | `cafe/preferences` |
| Cafe / Logic / Profile & Settings | Phone Change — current code | POST | `cafe/phone-change/current-code` |
| Cafe / Logic / Profile & Settings | Phone Change — verify | POST | `cafe/phone-change/verify` |
| Cafe / Logic / Profile & Settings | Phone Change — new code | POST | `cafe/phone-change/new-code` |
| Cafe / Logic / Profile & Settings | Phone Change — resend | POST | `cafe/phone-change/resend` |
| Cafe / Logic / Profile & Settings | Delete Account | DELETE | `cafe/account` |
| Cafe / Logic / Packages & Subscriptions | List Packages | GET | `cafe/packages` |
| Cafe / Logic / Packages & Subscriptions | Show Package | GET | `cafe/packages/{{package_id}}` |
| Cafe / Logic / Packages & Subscriptions | Subscription Quote | POST | `cafe/subscriptions/quote` |
| Cafe / Logic / Packages & Subscriptions | Place Subscription | POST | `cafe/subscriptions` |
| Cafe / Logic / Packages & Subscriptions | Current Subscription | GET | `cafe/subscriptions/current` |
| Cafe / Logic / Packages & Subscriptions | List Subscriptions | GET | `cafe/subscriptions` |
| Cafe / Logic / Packages & Subscriptions | Show Payment | GET | `cafe/payments/{{payment_id}}` |
| Cafe / Logic / Events | List Events | GET | `cafe/events` |
| Cafe / Logic / Events | Create Event | POST | `cafe/events` |
| Cafe / Logic / Events | Show Event | GET | `cafe/events/{{event_id}}` |
| Cafe / Logic / Events | Update Event | PUT (POST override) | `cafe/events/{{event_id}}` |
| Cafe / Logic / Events | Stop Event | POST | `cafe/events/{{event_id}}/stop` |
| Cafe / Logic / Events | Resume Event | POST | `cafe/events/{{event_id}}/resume` |
| Cafe / Logic / Events | Delete Event | DELETE | `cafe/events/{{event_id}}` |
| Cafe / Logic / Events | Event QR Codes | GET | `cafe/events/{{event_id}}/qr-codes` |
| Cafe / Logic / Events | Event Sections | GET | `cafe/events/{{event_id}}/sections` |
| Cafe / Logic / Sections & Questions | Create Question | POST | `cafe/events/{{event_id}}/sections/{{section_id}}/questions` |
| Cafe / Logic / Sections & Questions | Update Question | PUT (POST override) | `cafe/events/{{event_id}}/sections/{{section_id}}/questions/{{question_id}}` |
| Cafe / Logic / Sections & Questions | Delete Question | DELETE | `cafe/events/{{event_id}}/sections/{{section_id}}/questions/{{question_id}}` |
| Cafe / Logic / Rewards | Resolve Reward QR | POST | `cafe/rewards/resolve` |
| Cafe / Logic / Rewards | Redeem Reward | POST | `cafe/rewards/{{reward_id}}/redeem` |
| Cafe / Logic / Dashboard & Reports | Dashboard | GET | `cafe/dashboard` |
| Cafe / Logic / Dashboard & Reports | Events Report List | GET | `cafe/reports/events` |
| Cafe / Logic / Dashboard & Reports | Single Event Report | GET | `cafe/events/{{event_id}}/report` |
| Cafe / Logic / Dashboard & Reports | Create Report Export | POST | `cafe/reports/exports` |
| Cafe / Logic / Dashboard & Reports | Show Export | GET | `cafe/reports/exports/{{export_id}}` |
| Cafe / Logic / Dashboard & Reports | Download Export | GET | `cafe/reports/exports/{{export_id}}/download` |
| Cafe / Logic / Notifications | List Notifications | GET | `cafe/notifications` |
| Cafe / Logic / Notifications | Mark Read | POST | `cafe/notifications/{{notification_id}}/read` |
| Cafe / Logic / Notifications | Mark All Read | POST | `cafe/notifications/read-all` |
| Public / CMS & Static | Change Lang | GET | `general/change-lang` |
| Public / CMS & Static | Terms | GET | `general/terms/{{terms_type}}` |
| Public / CMS & Static | About | GET | `general/about` |
| Public / CMS & Static | Who We Are | GET | `general/who-we-are` |
| Public / CMS & Static | Privacy | GET | `general/privacy` |
| Public / CMS & Static | Page by Slug | GET | `general/pages/{{page_slug}}` |
| Public / CMS & Static | Splash Pages | GET | `general/splash-pages` |
| Public / CMS & Static | FAQs | GET | `general/fqs` |
| Public / CMS & Static | Socials | GET | `general/socials` |
| Public / CMS & Static | Sliders | GET | `general/sliders` |
| Public / Countries | Countries | GET | `general/countries` |
| Public / Countries | Country Cities | GET | `general/countries/{{country_id}}/cities` |
| Public / Support & Payments | Complaint (public) | POST | `general/complaints` |
| Public / Support & Payments | Payment Methods | GET | `general/payment-methods` |
| Public / Payments Webhooks | Payment Gateway Webhook | POST | `integrations/payments/{{gateway}}/webhook` |
| Chat / User | List Chats | GET | `user/chats` |
| Chat / User | Show Chat Room | GET | `user/chats/{{room_id}}` |
| Chat / User | List Messages | GET | `user/chats/{{room_id}}/messages` |
| Chat / User | Send Message | POST | `user/chats/{{room_id}}/messages` |
| Chat / User | Mark Chat Read | POST | `user/chats/{{room_id}}/read` |
| Chat / User | Block User | POST | `user/blocks` |
| Chat / User | Report Chat | POST | `user/reports` |
| Chat / User | Socket Token | GET | `user/socket-token` |
