Skip to main content

Points FAQ

Background​

On Shukah the app reads the points questions and answers with GET /maeda/points-faq. Locate's GET /api/v2/client/points-faq returns the same list, and on dev the five items were identical to Shukah's on 2026-10-01 and again on 2026-10-02, key for key. The one thing that changes is the token: Locate needs one, and on dev today it must be a Shukah token, while Shukah's route answered without one.

Feature​

The FAQ is a list of questions and answers about points: what a point is worth, how to earn points, how to use them. It is the same list for every client. In the app snapshot of 2026-02-26 the call happens once, when the Wallet screen shows its FAQ section. The app shows nothing when the list is empty.

Every item carries both languages: title_ar, text_ar, title_en and text_en. The server always sends all four, and the app chooses which pair to show. language is not read by the point service, and order-v2 does not forward a query on this route, so the language the app adds to every call is dropped.

Only a Shukah token works on dev today: a Locate JWT got 401 Invalid or expired token on this route on 2026-10-02, although both tokens worked on the balance route on 2026-10-01 (see Which tokens work). order-v2 passes the call to the point service and returns the answer unchanged.

GET /api/v2/client/points-faq​

Replaces ShukahGET /maeda/points-faq✅ Replaced
Drop-in0 breaking · 3 to watch
  • 🟡 Locate needs a token; Shukah answered 200 with none; the app always sends one
  • 🟡 Locate JWT gets 401 on dev; send the Shukah token
  • 🟡 Five items deep-equal incl. \r\n; the FAQ's earn text matches neither rate table

The five FAQ entries are identical to Shukah on dev, but Locate needs a token where Shukah answered without one.

Request​

FieldInTypeRequiredConstraintsDescription
AuthorizationheaderstringyesBearer <token>: a Shukah token on dev today. A Locate JWT gets 401 Invalid or expired token (captured on dev, 2026-10-02): see Which tokens work.The client's own token.
languagequerystringnoAccepted and ignored: all four fields are always returned. order-v2 does not forward it.Kept so the old Shukah query string still works.

Response​

200 with a bare array. The keys of each item come in this order: title_ar, text_ar, title_en, text_en. The array follows the order set in the FAQ settings and holds only the active items. On dev it had five items.

FieldTypeNullableFormat / constraintsDescription
title_arstringno"" when missing.The Arabic question.
text_arstringno"" when missing. Has \r\n line breaks.The Arabic answer.
title_enstringno"" when missing.The English question.
text_enstringno"" when missing. Has \r\n line breaks. One live item ends with \t \r\n.The English answer.
[
{
"title_ar": "كم قيمة النقطة في لوكيت؟",
"text_ar": "النقطة الواحدة تساوي 0.25 ريال.\r\nيعني 4 نقاط تساوي ريال واحد.",
"title_en": "How many points are worth in the Locate App?",
"text_en": "each point equal to 0.25 SR\r\nthat means, each 4 points equal to one SR"
}
]

Captured on dev, 2026-10-01 (client 356259): the first of five items.

The answer to "How I can earn points?" states an earn table with 35–69 SR for 1 point, 70–139 SR for 2, 140–250 SR for 4, 251–450 SR for 8 and 451 SR or more for 16. That matches neither earn-rate table captured the same day (see Points wallet). Which table is the right one: Not documented yet.

Errors​

HTTPBodyWhen
401{"success":false,"error":{"code":"UNAUTHORIZED","message":"Missing or invalid authorization header"}}There is no Authorization header, or it does not start with Bearer . Captured on dev, 2026-10-01, with no token.
401The same shape, with message Invalid or expired token, auth service unreachable: <error text> or auth response missing numeric client id.The auth service refused the token, could not be reached (an auth outage looks like a bad token), or answered without a client id. Invalid or expired token was captured on dev, 2026-10-02, with a Locate JWT.
500{"success":false,"error":{"code":"INTERNAL_ERROR","message":"Internal server error"}}Any unexpected failure in the point service, for example a database error. The message is AUTH_SERVICE_URL not set when the service is misconfigured. Not captured.
502{"success":false,"error":{"code":"POINT_SERVICE_UNAVAILABLE","message":"Point service unavailable: <error text>"}}order-v2 could not reach the point service. This body comes from order-v2, not from the point service. Not captured.
504{"success":false,"error":{"code":"POINT_SERVICE_TIMEOUT","message":"Point service did not respond in time; the request outcome is unknown"}}The point service did not answer within 10 seconds. This body comes from order-v2. Not captured.

Every error from the point service has the envelope {"success":false,"error":{"code":"…","message":"…"}}.

Try it​

export ORDER_BASE_URL=https://dev.v2.api.order.locate.sa
export SHUKAH_TOKEN='<shukah-token>' # a Locate JWT gets 401 here today; see "Which tokens work" on Points wallet
curl -s "$ORDER_BASE_URL/api/v2/client/points-faq" -H "Authorization: Bearer $SHUKAH_TOKEN"

Expected: 200 and an array of five items like the one shown under Response. Use a Shukah token on dev today: a Locate JWT gets 401 Invalid or expired token (2026-10-02). With no token you get the 401 shown under Errors.

Differences from Shukah​

The two five-item arrays were deep-equal on 2026-10-01 and on 2026-10-02, with the same key order and the same \r\n line breaks. The rows below cover the token, the URL and the error body.

AspectShukahLocateImpact on the app
URLGET $SHUKAH_BASE_URL/maeda/points-faqGET $ORDER_BASE_URL/api/v2/client/points-faqChange the base URL and the path.
TokenNone needed: 200 with no token (captured on dev, 2026-10-01).Required: 401 with no token (captured on dev, 2026-10-01). A Shukah token only on dev today: a Locate JWT gets 401 (2026-10-02).The app already sends its token on every call, and must keep it a Shukah token here. A screen that shows the FAQ before login would fail. Whether such a screen exists: Not documented yet.
Error bodyNot documented yet. The route is public, so there is no 401 to compare.The point-service envelope under Errors.Anything that matches on error text must change.
Content-Typeapplication/jsonapplication/json; charset=utf-8None.

Watch out​

  • Locate needs a token on this route, where Shukah's answered without one.
  • All four fields come back in every item, and language is ignored, so the app has to pick the Arabic or English pair itself.
  • The earn table written in the FAQ text matches neither earn-rate table on dev.

Details (for backend)​

Only dev was checked, through order-v2 at https://dev.v2.api.order.locate.sa, prefix /api/v2/client. UAT and production hosts: Not documented yet. In this section OV2: means locate-order-v2-api@d9e4e5f6 and PS: means locate-point-service@2c44ce3. How the proxy, the token check and the error envelope work is described once, under How the proxied calls work.

Route and proxy​

GET /api/v2/client/points-faq goes to GET /api/client/points-faq on the point service. order-v2 forwards Authorization only, with a 10 second limit, and no query (OV2: src/modules/client/point/point.controller.ts:47-59, PS: services/api/src/routes/client.routes.ts:19, PS: services/api/src/handlers/client-points-faq.ts:6-9).

What the point service reads​

It reads point_faqs rows with status: 'active', sorted by ordering from low to high, and flattens each {title:{en,ar}, text:{en,ar}} document into the four flat keys. A missing value becomes "" (PS: services/api/src/services/client-points.service.ts:43-50, PS: services/api/src/services/client-points.mappers.ts:58-71; tests PS: services/api/src/services/client-points.mappers.test.ts:88-107). The list is not specific to the client. The auth service's ETL fills point_faqs from Shukah's FAQ table; the client routes cannot write it (PS: docs/integrations/2026-07-16-client-facing-point-apis.md:172-174, PS: docs/2026-07-10-local-testing.md:53).

Parity​

On 2026-10-01 the Locate and Shukah arrays were compared by program and were deep-equal, with the same key order. In July the Locate list was an empty stub, so this closes that finding (PS: docs/reports/2026-07-17-client-api-parity.md:165-168). The point service doc already recorded equality after the 2026-07-17 implementation (PS: docs/integrations/2026-07-16-client-facing-point-apis.md:171-174).

The app​

The app turns each item into a title and body in English and in Arabic, shows the pair that matches the app language, uses the English title as the list key, and shows nothing for an empty list (mobile/locate-client@e960c3a: src/entities/points/model/api/dto/points.dto.ts:53-68, mobile/locate-client@e960c3a: src/features/PointsFaq/ui/FaqItem/FaqItem.tsx:32-37, mobile/locate-client@e960c3a: src/features/PointsFaq/ui/PointsFaq/PointsFaq.tsx:27-70). It calls the route with no query of its own (mobile/locate-client@e960c3a: src/entities/points/model/api/services/points.service.ts:62-76).

Where the docs and the code disagree (code wins)​

  • 2026-10-02: this page said a Shukah token and a Locate JWT both worked here. On 2026-10-02 the JWT got 401 Invalid or expired token, and the Try it now uses a Shukah token (PS: services/api/src/services/client-auth.service.ts:22-29; see Which tokens work).

Sources​

  • locate-order-v2-api@d9e4e5f6: src/modules/client/point/point.controller.ts:47-59
  • locate-point-service@2c44ce3: services/api/src/routes/client.routes.ts:19, services/api/src/handlers/client-points-faq.ts:6-9, services/api/src/services/client-points.service.ts:43-50, services/api/src/services/client-points.mappers.ts:58-71, services/api/src/services/client-points.mappers.test.ts:88-107
  • locate-point-service@2c44ce3 docs: docs/integrations/2026-07-16-client-facing-point-apis.md:171-174, docs/2026-07-10-local-testing.md:53, docs/reports/2026-07-17-client-api-parity.md:165-168
  • Mobile snapshot mobile/locate-client@e960c3a (branch development, 2026-02-26; the app's own code, not Locate): src/entities/points/model/api/services/points.service.ts:62-76, src/entities/points/model/api/dto/points.dto.ts:53-68, src/features/PointsFaq/ui/PointsFaq/PointsFaq.tsx:27-70, src/features/PointsFaq/ui/FaqItem/FaqItem.tsx:32-37, platforms/mobile/products/locate/screens/home/mainInner/Wallet/ui/Wallet/Wallet.tsx:84
  • Dev captures, 2026-10-02 (parity audit): points-faq--shukah, points-faq--locate-st, points-faq--locate-jwt, points-faq-notoken--shukah
  • Dev captures, 2026-10-01: locate-points-faq, shukah-points-faq, probe-locate-points-faq, probe-shukah-points-faq