Skip to content

Instantly share code, notes, and snippets.

@HelgeSverre
Last active February 20, 2026 01:46
Show Gist options
  • Select an option

  • Save HelgeSverre/80a7f34f874336324184a0c513c2e6a2 to your computer and use it in GitHub Desktop.

Select an option

Save HelgeSverre/80a7f34f874336324184a0c513c2e6a2 to your computer and use it in GitHub Desktop.
Norwegian Grocery Store APIs — Reverse-engineered API documentation for Rema 1000, Coop Norway, and Trumf (extracted from Android APKs)
{
"openapi": "3.1.0",
"info": {
"title": "Coop Norway Medlem API",
"version": "4.17.3",
"description": "Reverse-engineered API specification for the Coop Norway \"Coop medlem\" Android app (no.coop.members v4.17.3). Extracted via static analysis of the compiled Dart binary (libapp.so) from the Flutter APK.\n\nThis API powers Norway's Coop loyalty program including purchase history, digital receipts, coupons, Coopay mobile payment, shopping lists, and Shop Express.\n\n**Authentication:** OpenID Connect via Auth0 at https://login.coop.no/\n**Strong Customer Auth (Coopay):** Aera SDK at https://api.aerahost.com/\n\n⚠️ Unofficial, reverse-engineered spec. Use responsibly for personal data access only.",
"contact": { "name": "Helge Sverre", "url": "https://helgesver.re" },
"license": { "name": "MIT" }
},
"servers": [
{ "url": "https://api.coop.no", "description": "Production" },
{ "url": "https://api.staging.coop", "description": "Staging" }
],
"security": [{ "oidcAuth": [] }],
"tags": [
{ "name": "Purchases", "description": "Purchase history, receipts, and spending data" },
{ "name": "Coupons", "description": "Digital coupons and offers" },
{ "name": "Profile", "description": "User profile and preferences" },
{ "name": "Family", "description": "Family membership management" },
{ "name": "Coopay", "description": "Mobile payment (Coopay)" },
{ "name": "Parking", "description": "Parking history and stores" },
{ "name": "Vehicles", "description": "Vehicle registration for parking" },
{ "name": "Mastercard", "description": "Coop Mastercard management" },
{ "name": "BankAxept", "description": "BankAxept account linking" },
{ "name": "ShopExpress", "description": "Self-checkout scanning" },
{ "name": "Stores", "description": "Store information" },
{ "name": "Content", "description": "Articles, banners, recipes" },
{ "name": "Push", "description": "Push notification management" },
{ "name": "ShoppingList", "description": "gRPC shopping lists (handleliste.coop.no)" }
],
"paths": {
"/user/pay/history/dashboard": {
"get": {
"tags": ["Purchases"],
"operationId": "getPurchaseDashboard",
"summary": "Purchase dashboard overview",
"description": "Returns an overview of spending with monthly breakdowns. This is the main entry point for purchase data.",
"responses": {
"200": {
"description": "Dashboard data",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/PurchaseDashboardResponse" }
}
}
}
}
}
},
"/user/pay/history/list": {
"get": {
"tags": ["Purchases"],
"operationId": "getPurchaseHistoryList",
"summary": "Purchase history list",
"description": "Returns a list of purchase summary stubs grouped by month.",
"responses": {
"200": {
"description": "Purchase list",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/PurchaseHistoryResponse" }
}
}
}
}
}
},
"/user/pay/history/month": {
"get": {
"tags": ["Purchases"],
"operationId": "getPurchaseHistoryMonth",
"summary": "Monthly purchase breakdown",
"description": "Returns detailed purchase data for a specific month.",
"responses": {
"200": { "description": "Monthly purchase data" }
}
}
},
"/user/pay/history/details": {
"get": {
"tags": ["Purchases"],
"operationId": "getPurchaseDetails",
"summary": "Purchase details with line items",
"description": "Returns full purchase details including individual product line items with EAN codes, quantities, prices, and discounts.",
"responses": {
"200": {
"description": "Purchase details",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/PurchaseSummaryResponse" }
}
}
}
}
}
},
"/user/pay/history/search": {
"get": {
"tags": ["Purchases"],
"operationId": "searchPurchases",
"summary": "Search purchase history",
"parameters": [
{ "name": "searchQuery", "in": "query", "schema": { "type": "string" }, "description": "Search term (product name, store, etc.)" }
],
"responses": {
"200": {
"description": "Search results",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/PurchaseHistorySearchResponse" }
}
}
}
}
}
},
"/user/pay/history/search/continue": {
"get": {
"tags": ["Purchases"],
"operationId": "searchPurchasesContinue",
"summary": "Continue paginated purchase search",
"responses": { "200": { "description": "Next page of search results" } }
}
},
"/user/pay/history/receipt.pdf": {
"get": {
"tags": ["Purchases"],
"operationId": "getReceiptPdf",
"summary": "Download receipt as PDF",
"parameters": [
{ "name": "receiptid", "in": "query", "required": true, "schema": { "type": "string" }, "description": "Receipt/summary ID" }
],
"responses": {
"200": {
"description": "Receipt PDF",
"content": { "application/pdf": { "schema": { "type": "string", "format": "binary" } } }
}
}
}
},
"/coupon/all": {
"get": {
"tags": ["Coupons"],
"operationId": "getAllCoupons",
"summary": "Get all available coupons",
"responses": {
"200": {
"description": "Coupon list",
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/CouponResponse" } } }
}
}
}
},
"/coupon/activate": {
"post": {
"tags": ["Coupons"],
"operationId": "activateCoupon",
"summary": "Activate a coupon",
"requestBody": {
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/CouponActivationRequest" } } }
},
"responses": { "200": { "description": "Coupon activated" } }
}
},
"/coupon/swap": {
"post": {
"tags": ["Coupons"],
"operationId": "swapCoupon",
"summary": "Swap a coupon for a different one",
"responses": { "200": { "description": "Coupon swapped" } }
}
},
"/user/myoffers": {
"get": {
"tags": ["Coupons"],
"operationId": "getMyOffers",
"summary": "Get personalized offers",
"responses": { "200": { "description": "Personal offers" } }
}
},
"/store/all": {
"get": {
"tags": ["Stores"],
"operationId": "getAllStores",
"summary": "Get all Coop stores",
"responses": {
"200": {
"description": "Store list",
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/StoreListResponse" } } }
}
}
}
},
"/user/profile": {
"get": {
"tags": ["Profile"],
"operationId": "getUserProfile",
"summary": "Get user profile",
"responses": { "200": { "description": "User profile data" } }
}
},
"/user/benefits/overview": {
"get": {
"tags": ["Profile"],
"operationId": "getBenefitsOverview",
"summary": "Member benefits overview",
"responses": { "200": { "description": "Benefits data" } }
}
},
"/user/content/memberbenefits": {
"get": {
"tags": ["Profile"],
"operationId": "getMemberBenefitsContent",
"summary": "Detailed member benefits content",
"responses": { "200": { "description": "Member benefits content" } }
}
},
"/user/terms": { "get": { "tags": ["Profile"], "operationId": "getTerms", "summary": "Terms and conditions", "responses": { "200": { "description": "Terms" } } } },
"/user/legaltext": { "get": { "tags": ["Profile"], "operationId": "getLegalText", "summary": "Legal text", "responses": { "200": { "description": "Legal text" } } } },
"/user/newsfeed": { "get": { "tags": ["Content"], "operationId": "getNewsfeed", "summary": "News feed", "responses": { "200": { "description": "News items" } } } },
"/user/content/articles": { "get": { "tags": ["Content"], "operationId": "getArticles", "summary": "Content articles", "responses": { "200": { "description": "Articles" } } } },
"/user/content/banners": { "get": { "tags": ["Content"], "operationId": "getBanners", "summary": "Promotional banners", "responses": { "200": { "description": "Banners" } } } },
"/user/content/recipes": { "get": { "tags": ["Content"], "operationId": "getRecipes", "summary": "Recipes", "responses": { "200": { "description": "Recipes" } } } },
"/user/new_device": { "post": { "tags": ["Profile"], "operationId": "registerNewDevice", "summary": "Register new device", "responses": { "200": { "description": "Device registered" } } } },
"/user/consent/MARKETING_ANALYSIS": { "post": { "tags": ["Profile"], "operationId": "setMarketingConsent", "summary": "Set marketing analysis consent", "responses": { "200": { "description": "Consent updated" } } } },
"/user/ageverification/consent": { "post": { "tags": ["Profile"], "operationId": "setAgeVerificationConsent", "summary": "Age verification consent", "responses": { "200": { "description": "Consent set" } } } },
"/user/feedback/nps": { "post": { "tags": ["Profile"], "operationId": "submitNpsFeedback", "summary": "Submit NPS feedback", "responses": { "200": { "description": "Feedback submitted" } } } },
"/user/feedback/config": { "get": { "tags": ["Profile"], "operationId": "getFeedbackConfig", "summary": "Get feedback configuration", "responses": { "200": { "description": "Feedback config" } } } },
"/user/dynalink/resolve": { "post": { "tags": ["Profile"], "operationId": "resolveDynamicLink", "summary": "Resolve dynamic link", "responses": { "200": { "description": "Resolved link" } } } },
"/user/family/myfamily": { "get": { "tags": ["Family"], "operationId": "getMyFamily", "summary": "Get family members", "responses": { "200": { "description": "Family data" } } } },
"/user/family/send_invitation": { "post": { "tags": ["Family"], "operationId": "sendFamilyInvitation", "summary": "Invite family member", "responses": { "200": { "description": "Invitation sent" } } } },
"/user/family/revoke_invitation": { "post": { "tags": ["Family"], "operationId": "revokeFamilyInvitation", "summary": "Revoke family invitation", "responses": { "200": { "description": "Invitation revoked" } } } },
"/user/family/remove_member": { "post": { "tags": ["Family"], "operationId": "removeFamilyMember", "summary": "Remove family member", "responses": { "200": { "description": "Member removed" } } } },
"/user/pay/": { "get": { "tags": ["Coopay"], "operationId": "getPaymentOverview", "summary": "Coopay payment overview", "responses": { "200": { "description": "Payment overview" } } } },
"/user/pay/activate": { "post": { "tags": ["Coopay"], "operationId": "activateCoopay", "summary": "Activate Coopay", "responses": { "200": { "description": "Coopay activated" } } } },
"/user/pay/activate/device": { "post": { "tags": ["Coopay"], "operationId": "activateDevice", "summary": "Activate device for Coopay", "responses": { "200": { "description": "Device activated" } } } },
"/user/pay/deactivate": { "post": { "tags": ["Coopay"], "operationId": "deactivateCoopay", "summary": "Deactivate Coopay", "responses": { "200": { "description": "Coopay deactivated" } } } },
"/user/pay/delete": { "post": { "tags": ["Coopay"], "operationId": "deleteCoopay", "summary": "Delete Coopay account", "responses": { "200": { "description": "Coopay deleted" } } } },
"/user/pay/devices": { "get": { "tags": ["Coopay"], "operationId": "getCoopayDevices", "summary": "List Coopay devices", "responses": { "200": { "description": "Device list" } } } },
"/user/pay/scancodes": { "get": { "tags": ["Coopay"], "operationId": "getPaymentScanCodes", "summary": "Get payment QR/scan codes", "responses": { "200": { "description": "Scan codes" } } } },
"/user/pay/get-new-approval-inquiry": { "get": { "tags": ["Coopay"], "operationId": "getApprovalInquiry", "summary": "Get new payment approval inquiry", "responses": { "200": { "description": "Approval inquiry" } } } },
"/user/pay/get-payment-result": { "get": { "tags": ["Coopay"], "operationId": "getPaymentResult", "summary": "Get payment result", "responses": { "200": { "description": "Payment result" } } } },
"/user/pay/update-approval": { "post": { "tags": ["Coopay"], "operationId": "updatePaymentApproval", "summary": "Accept or reject payment", "responses": { "200": { "description": "Approval updated" } } } },
"/user/pay/event": { "post": { "tags": ["Coopay"], "operationId": "postPaymentEvent", "summary": "Post payment event", "responses": { "200": { "description": "Event posted" } } } },
"/user/pay/bankid/identify": { "post": { "tags": ["Coopay"], "operationId": "bankIdIdentify", "summary": "BankID identification", "responses": { "200": { "description": "BankID response" } } } },
"/user/pay/bankid/hwp": { "post": { "tags": ["Coopay"], "operationId": "bankIdHwp", "summary": "BankID HWP request", "responses": { "200": { "description": "HWP response" } } } },
"/user/pay/wallet/prepsign": { "post": { "tags": ["Coopay"], "operationId": "walletPrepSign", "summary": "Prepare wallet signing", "responses": { "200": { "description": "Prep sign data" } } } },
"/user/pay/wallet/hwp": { "post": { "tags": ["Coopay"], "operationId": "walletHwp", "summary": "Wallet HWP request", "responses": { "200": { "description": "HWP response" } } } },
"/user/pay/offline/debt": { "get": { "tags": ["Coopay"], "operationId": "getOfflineDebt", "summary": "Get offline payment debt", "responses": { "200": { "description": "Offline debt" } } } },
"/user/pay/offline/params": { "get": { "tags": ["Coopay"], "operationId": "getOfflineParams", "summary": "Get offline payment parameters", "responses": { "200": { "description": "Offline params" } } } },
"/user/pay/offline/trigger": { "post": { "tags": ["Coopay"], "operationId": "triggerOfflinePayment", "summary": "Trigger offline payment", "responses": { "200": { "description": "Payment triggered" } } } },
"/user/parking/history": { "get": { "tags": ["Parking"], "operationId": "getParkingHistory", "summary": "Get parking history", "responses": { "200": { "description": "Parking records" } } } },
"/user/parking/stores": { "get": { "tags": ["Parking"], "operationId": "getParkingStores", "summary": "Get stores with parking", "responses": { "200": { "description": "Parking stores" } } } },
"/user/vehicle/list": { "get": { "tags": ["Vehicles"], "operationId": "listVehicles", "summary": "List registered vehicles", "responses": { "200": { "description": "Vehicle list" } } } },
"/user/vehicle/add": { "post": { "tags": ["Vehicles"], "operationId": "addVehicle", "summary": "Register a vehicle", "responses": { "200": { "description": "Vehicle added" } } } },
"/user/vehicle/update": { "post": { "tags": ["Vehicles"], "operationId": "updateVehicle", "summary": "Update vehicle details", "responses": { "200": { "description": "Vehicle updated" } } } },
"/user/vehicle/remove": { "post": { "tags": ["Vehicles"], "operationId": "removeVehicle", "summary": "Remove a vehicle", "responses": { "200": { "description": "Vehicle removed" } } } },
"/user/vehicle/lookup": { "get": { "tags": ["Vehicles"], "operationId": "lookupVehicle", "summary": "Lookup vehicle by plate", "responses": { "200": { "description": "Vehicle info" } } } },
"/user/mastercard/": { "get": { "tags": ["Mastercard"], "operationId": "getMastercardOverview", "summary": "Coop Mastercard overview", "responses": { "200": { "description": "Mastercard overview" } } } },
"/user/mastercard/card-info": { "get": { "tags": ["Mastercard"], "operationId": "getMastercardInfo", "summary": "Get card info", "responses": { "200": { "description": "Card info" } } } },
"/user/mastercard/movements": { "get": { "tags": ["Mastercard"], "operationId": "getMastercardMovements", "summary": "Get card transactions/movements", "responses": { "200": { "description": "Movements" } } } },
"/user/bankaxept/account-number": { "get": { "tags": ["BankAxept"], "operationId": "getBankAxeptAccount", "summary": "Get linked BankAxept account", "responses": { "200": { "description": "Account number" } } } },
"/user/bankaxept/enrollment": { "post": { "tags": ["BankAxept"], "operationId": "enrollBankAxept", "summary": "Enroll BankAxept", "responses": { "200": { "description": "Enrolled" } } } },
"/user/shopexpress/stores": { "get": { "tags": ["ShopExpress"], "operationId": "getShopExpressStores", "summary": "Stores with Shop Express", "responses": { "200": { "description": "Store list" } } } },
"/user/shopexpress/shoppingtrip/init": { "post": { "tags": ["ShopExpress"], "operationId": "initShoppingTrip", "summary": "Start a Shop Express trip", "responses": { "200": { "description": "Trip initialized" } } } },
"/user/shopexpress/shoppingtrip/add_cart_item": { "post": { "tags": ["ShopExpress"], "operationId": "addCartItem", "summary": "Scan and add item to cart", "responses": { "200": { "description": "Item added" } } } },
"/user/shopexpress/shoppingtrip/status": { "get": { "tags": ["ShopExpress"], "operationId": "getTripStatus", "summary": "Get shopping trip status", "responses": { "200": { "description": "Trip status" } } } },
"/push/register": { "post": { "tags": ["Push"], "operationId": "registerPush", "summary": "Register for push notifications", "responses": { "200": { "description": "Registered" } } } },
"/push/unregister": { "post": { "tags": ["Push"], "operationId": "unregisterPush", "summary": "Unregister from push notifications", "responses": { "200": { "description": "Unregistered" } } } }
},
"components": {
"securitySchemes": {
"oidcAuth": {
"type": "openIdConnect",
"openIdConnectUrl": "https://login.coop.no/.well-known/openid-configuration",
"description": "Auth0-hosted OpenID Connect. Use Authorization Code with PKCE (S256). Redirect URI: no.coop.members://auth/callback"
}
},
"schemas": {
"PurchaseDashboardResponse": {
"type": "object",
"properties": {
"dashboardTotal": { "type": "number", "description": "Total spending amount" },
"monthlyBreakdown": { "type": "array", "items": { "$ref": "#/components/schemas/MonthlyBreakdown" } }
}
},
"MonthlyBreakdown": {
"type": "object",
"properties": {
"month": { "type": "integer" },
"year": { "type": "integer" },
"amount": { "type": "number" }
}
},
"PurchaseHistoryResponse": {
"type": "object",
"properties": {
"purchases": { "type": "array", "items": { "$ref": "#/components/schemas/PurchaseSummaryStub" } }
}
},
"PurchaseSummaryStub": {
"type": "object",
"properties": {
"summaryId": { "type": "string", "description": "Unique purchase identifier" },
"purchaseDate": { "type": "string", "format": "date-time" },
"storeName": { "type": "string" },
"storeId": { "type": "string" },
"chainId": { "type": "string", "description": "Coop chain identifier (Extra, Prix, Mega, Obs, etc.)" },
"amount": { "type": "number", "description": "Total amount in NOK" },
"totalDiscount": { "type": "number", "description": "Total discount in NOK" }
}
},
"PurchaseSummaryStubMonthGroup": {
"type": "object",
"properties": {
"month": { "type": "integer" },
"year": { "type": "integer" },
"purchases": { "type": "array", "items": { "$ref": "#/components/schemas/PurchaseSummaryStub" } }
}
},
"PurchaseSummaryResponse": {
"type": "object",
"properties": {
"summary": { "$ref": "#/components/schemas/PurchaseSummary" }
}
},
"PurchaseSummary": {
"type": "object",
"description": "Full purchase details including line items",
"properties": {
"summaryId": { "type": "string" },
"receiptId": { "type": "string" },
"purchaseDate": { "type": "string", "format": "date-time" },
"storeName": { "type": "string" },
"storeId": { "type": "string" },
"chainId": { "type": "string" },
"amount": { "type": "number" },
"totalDiscount": { "type": "number" },
"totalDiscountFormatted": { "type": "string", "description": "Formatted discount string (e.g. 'kr 42,50')" },
"memberBonus": { "type": "number", "description": "Member bonus earned" },
"lines": { "type": "array", "items": { "$ref": "#/components/schemas/PurchaseSummaryLine" } }
}
},
"PurchaseSummaryLine": {
"type": "object",
"description": "Individual product line item on a receipt",
"properties": {
"productName": { "type": "string" },
"ean13": { "type": "string", "description": "EAN-13 barcode" },
"gtin13": { "type": "string", "description": "GTIN-13 barcode" },
"barcode": { "type": "string", "description": "Barcode value" },
"quantity": { "type": "number" },
"amount": { "type": "number", "description": "Line total in NOK" },
"discount": { "type": "number", "description": "Discount on this line" },
"discountAmountPerQuantity": { "type": "number" },
"unitPrice": { "type": "number", "description": "Price per unit" }
}
},
"PurchaseHistorySearchResponse": {
"type": "object",
"properties": {
"searchQuery": { "type": "string" },
"purchases": { "type": "array", "items": { "$ref": "#/components/schemas/PurchaseSummaryStub" } }
}
},
"CouponResponse": {
"type": "object",
"properties": {
"coupons": { "type": "array", "items": { "$ref": "#/components/schemas/Coupon" } }
}
},
"Coupon": {
"type": "object",
"properties": {
"id": { "type": "string" },
"title": { "type": "string" },
"description": { "type": "string" },
"discountAmount": { "type": "number" },
"expiresAt": { "type": "string", "format": "date-time" },
"activated": { "type": "boolean" },
"tags": { "type": "array", "items": { "$ref": "#/components/schemas/CouponTag" } }
}
},
"CouponTag": {
"type": "object",
"properties": {
"name": { "type": "string" },
"value": { "type": "string" }
}
},
"CouponActivationRequest": {
"type": "object",
"properties": {
"couponId": { "type": "string" }
}
},
"StoreListResponse": {
"type": "object",
"properties": {
"stores": { "type": "array", "items": { "$ref": "#/components/schemas/Store" } }
}
},
"Store": {
"type": "object",
"properties": {
"storeId": { "type": "string" },
"storeName": { "type": "string" },
"chainId": { "type": "string" }
}
},
"Membership": {
"type": "object",
"properties": {
"membershipNumber": { "type": "string" },
"name": { "type": "string" },
"scanCode": { "type": "string", "description": "Barcode for in-store scanning" },
"qrCodeExpiryTime": { "type": "string", "format": "date-time" }
}
},
"MemberBonus": {
"type": "object",
"properties": {
"memberBonus": { "type": "number" },
"memberBonuses": { "type": "array", "items": { "type": "object" } }
}
}
}
}
}

Norwegian Grocery Store APIs — Reverse Engineering Documentation

Comprehensive API documentation for Rema 1000 (Æ), Coop Norway (Coop Medlem), and Trumf (NorgesGruppen), reverse-engineered from their Android apps. Use responsibly — this is for accessing your own purchase data.

Table of Contents


Overview

These APIs were extracted by decompiling Android APKs from Norway's three major grocery chains. Together, they cover ~97% of the Norwegian grocery market.

Chain App Package Version Tech Stack Method
Rema 1000 Æ no.rema.bella 3.0.12 Kotlin, Retrofit2, OkHttp3 jadx decompilation
Coop Norway Coop Medlem no.coop.members 4.17.3 Flutter (Dart → ARM32) strings on libapp.so
Trumf Trumf Web/API Open source (ttyridal)

What you can access: Purchase history, individual receipts with line items (product name, EAN barcode, price, quantity, discounts), offers/coupons, store data, and more.

⚠️ Disclaimer: These are private APIs not intended for third-party use. They can change without notice. Only use to access your own data. Respect rate limits.


Rema 1000 (Æ) API

Authentication

OAuth 2.0 Authorization Code with PKCE via Rema's identity provider.

Parameter Value
Authorization endpoint https://id.rema.no/authorization
Token endpoint https://id.rema.no/token
Client ID android-251010
Response type code (with PKCE / CodeVerifier)
Scope all
Redirect URI https://ae-appen.appspot.com/redirect/redirect.html

Token refresh: POST https://id.rema.no/token with grant_type=refresh_token

Required Headers

Every API request must include:

Authorization: Bearer <access_token>
ocp-apim-subscription-key: fb5e24884b504d0bad761098f77e6605
x-platform: android
x-correlation-id: <random UUID>
x-device-id: <device UUID>
x-mobile-nr: <phone number>
x-app: bella
x-app-version: 3.0.12 #110549

Base URL

https://api.rema.no

Transactions / Receipts

List all purchases

GET /v1/bella/transaction/v2/heads

Response:

{
  "bonusTotal": 0,
  "purchaseTotal": 4250.80,
  "discountTotal": 312.50,
  "transactions": [
    {
      "purchaseDate": 1600695669000,
      "storeId": "7080",
      "amount": 249.90,
      "storeName": "Rema 1000 Storgate",
      "id": 11223344556,
      "receiptNbr": "2009210000123123123123123"
    }
  ]
}
  • purchaseDate is a Unix timestamp in milliseconds
  • id is the transaction ID used for fetching line items

Get receipt line items

GET /v1/bella/transaction/v2/rows/{transactionId}

Response (array of line items):

[
  {
    "prodtxt1": "NORVEGIA 1KG",
    "prodtxt2": "",
    "prodtxt3": "7038010009457",
    "productCode": "109457",
    "productDescription": "Norvegia 26% 1kg",
    "productGroupDescription": "Ost",
    "unitPrice": 109.90,
    "amount": 109.90,
    "discount": 20.00,
    "usedOffers": []
  }
]
  • prodtxt3 is the EAN-13 barcode — globally unique product identifier
  • usedOffers lists any offers/coupons applied to this item

Get receipt by ID

GET /v1/bellanaveo/receipt/{receiptId}/{customerId}

Offers

Method Endpoint Description
GET /v1/bella/offers/v2/available-offers/ List available offers
POST /v1/bella/offers/activate Activate an offer
GET /v1/bella/offers/v2/offer-group/findgroup/{code} Get group offers
POST /v1/bella/offers/v2/offer-group/{code}/activate Activate group offer

Customer

Method Endpoint Description
GET /bella/v2/customers Get full customer profile
PUT /bella/v2/customers Update profile
GET /v1/bella/customers/v2/minimal Get minimal preferences
GET /v1/bella/customers/lottery Offer counters
GET /v1/bella/customers/getConsentsAndCommunicationChoices GDPR consents
GET /bella/v2/allergens/member Allergen preferences
PUT /bella/v2/allergens/setAllergens Update allergens
DELETE /v1/bella/user Delete account

Stores

Method Endpoint Description
GET /v1/bella/workplace/{id} Get store by ID
GET /v1/bella/workplace/search/{query} Search stores
GET /v1/bella/api/Geolocation?Latitude=&Longitude= Find nearest store
GET /v1/storespublic/{id} Public store info (no auth)

Shopping Lists

Method Endpoint Description
GET /shoppinglist/lists Get all lists
GET /shoppinglist/{listId} Get single list
POST /shoppinglist/events Add/remove/check items
POST /shoppinglist/multipleEvents Batch item events
POST /shoppinglist/generateLink Create share link
GET /shoppinglist/getlistinfojoin?hash= Get invite info
POST /shoppinglist/joinlist Accept invite
POST /shoppinglist/leavelist Leave shared list
WebSocket wss://api.rema.no/shoppinglistpubsub?access_token= Real-time sync

Product / Article Search

Method Endpoint Description
GET /articleSearch/v1/search?q=&rows=&page=&storeId= Search products
GET /v1/articles/gtin/{gtin} Get product by EAN/GTIN
POST /v1/articles/gtins?app Batch get product thumbnails

Product images: https://mediastore.tradesolution.no/api/products/{gtin}/image

Scan & Pay (Datema)

Method Endpoint Description
POST /v1/bellashoppingtrip/Sites/{storeNumber}/ShoppingTrips Start trip
POST …/ShoppingTrips/{tripId}/Items Add scanned item
PUT …/ShoppingTrips/{tripId}/Items/{itemId} Update quantity
DELETE …/ShoppingTrips/{tripId}/Items/{itemId} Remove item
PUT …/ShoppingTrips/{tripId}/End Finalize & pay

Cards & Payment

Method Endpoint Description
GET /v1/bellacards/list List payment cards
POST /v1/bellacards/session Create card session (Storebox)
POST /v1/bellacards/account Add Vipps account
GET /v1/bellacards/vipps/accounts Get Vipps accounts
POST /bellapayment/initiate/{cartId} Start payment
GET /bellapayment/status/{cartId} Payment status

GDPR / Data Access

Method Endpoint Description
GET /v1/sardar/DataAccessRequest List data access requests
POST /v1/sardar/DataAccessRequest Submit data access request
GET /v1/sardar/SubjectAccessRequest List subject access requests
POST /v1/sardar/SubjectAccessRequest Submit SAR (GDPR Art. 15)

Key Configuration Values

Key Value
API Subscription Key fb5e24884b504d0bad761098f77e6605
Articles Subscription Key 95477597247845f78d19b24549365df0
Public Stores Key d5badff9cde84923a49b4906bd2f1509
Papirfly Key 409c75b6cc0741fc98d4c1e978ed3a38
IDP Client ID android-251010
Vipps Client ID 010c2113-6003-432b-9ce0-2a842dc1b777
Firebase Project ae-appen
Google API Key AIzaSyA7LdW452m6smts7_dw3qatidrYlF2zR4M

Security Notes

  • No certificate pinning — no CertificatePinner, no network_security_config.xml
  • Tokens stored in EncryptedSharedPreferences
  • IDP sync token required for mutations (HEAD /synctoken → cookie + x-sync-token headers)
  • All traffic interceptable with mitmproxy

Coop Norway (Coop Medlem) API

Authentication

OpenID Connect via Auth0 (custom domain).

Parameter Value
Issuer https://login.coop.no/
Well-known https://login.coop.no/.well-known/openid-configuration
Authorization https://login.coop.no/authorize
Token https://login.coop.no/oauth/token
Userinfo https://login.coop.no/userinfo
Revocation https://login.coop.no/oauth/revoke
Logout https://login.coop.no/v2/logout
Redirect URI no.coop.members://auth/callback
PKCE S256
Scopes openid, profile, offline_access, email, phone, address

Strong Customer Authentication (Coopay): Aera SDK via https://api.aerahost.com/ — used for BankID verification and payment signing.

Base URL

https://api.coop.no

Staging: https://api.staging.coop

Purchase History / Receipts

These are the key endpoints for receipt data:

Method Endpoint Description
GET /user/pay/history/dashboard Spending overview with monthly totals
GET /user/pay/history/list Purchase list (summary stubs)
GET /user/pay/history/month Monthly breakdown
GET /user/pay/history/details Full receipt with line items
GET /user/pay/history/search?searchQuery= Search purchases
GET /user/pay/history/search/continue Paginate search
GET /user/pay/history/receipt.pdf?receiptid= Download receipt PDF

Data model (from Dart class analysis):

PurchaseSummary {
  summaryId, receiptId, purchaseDate,
  storeName, storeId, chainId,
  amount, totalDiscount, totalDiscountFormatted,
  memberBonus,
  lines: PurchaseSummaryLine[]
}

PurchaseSummaryLine {
  productName, ean13, gtin13, barcode,
  quantity, amount, discount,
  discountAmountPerQuantity, unitPrice
}

Coupons & Offers

Method Endpoint Description
GET /coupon/all All available coupons
POST /coupon/activate Activate a coupon
POST /coupon/swap Swap coupon
GET /user/myoffers Personalized offers

Stores & Content

Method Endpoint Description
GET /store/all All Coop stores
GET /user/newsfeed News feed
GET /user/content/articles Articles
GET /user/content/banners Promotional banners
GET /user/content/recipes Recipes

Profile & Family

Method Endpoint Description
GET /user/profile User profile
GET /user/benefits/overview Member benefits
GET /user/content/memberbenefits Benefits content
GET /user/family/myfamily Family members
POST /user/family/send_invitation Invite family member
POST /user/family/remove_member Remove member

Payment (Coopay)

Method Endpoint Description
GET /user/pay/ Payment overview
POST /user/pay/activate Activate Coopay
POST /user/pay/activate/device Activate device
GET /user/pay/devices List devices
GET /user/pay/scancodes Get payment QR codes
GET /user/pay/get-new-approval-inquiry Payment approval
GET /user/pay/get-payment-result Payment result
POST /user/pay/update-approval Accept/reject payment
POST /user/pay/bankid/identify BankID verification
POST /user/pay/wallet/prepsign Wallet signing
GET /user/pay/offline/debt Offline payment debt

Parking & Vehicles

Method Endpoint Description
GET /user/parking/history Parking history
GET /user/parking/stores Stores with parking
GET /user/vehicle/list Registered vehicles
POST /user/vehicle/add Add vehicle
POST /user/vehicle/remove Remove vehicle

Mastercard & BankAxept

Method Endpoint Description
GET /user/mastercard/card-info Coop Mastercard info
GET /user/mastercard/movements Card transactions
GET /user/bankaxept/account-number Linked account
POST /user/bankaxept/enrollment Enroll BankAxept

Shop Express (Scan & Go)

Method Endpoint Description
GET /user/shopexpress/stores Available stores
POST /user/shopexpress/shoppingtrip/init Start trip
POST /user/shopexpress/shoppingtrip/add_cart_item Scan item
POST /user/shopexpress/shoppingtrip/update_quantity Update qty
GET /user/shopexpress/shoppingtrip/status Trip status

gRPC Services (Shopping Lists)

Base: https://handleliste.coop.no
Protocol: gRPC (application/grpc)

Service Method Description
coopnorge.offers.v1beta1.OffersAPI Get Get offers
coopnorge.shoppinglist.v2beta1.ShoppingListAPI GetShoppingLists List shopping lists
CreateShoppingList Create new list
DeleteShoppingList Delete list
AddEntries Add items
GetEntries Get list items
RemoveEntries Remove items
CheckEntries Check off items
SetEntriesQuantity Update quantities
ShareShoppingList Generate share link
AcceptInvitation Join shared list
SearchProducts Search for products
Watch Real-time updates (streaming)

Key Configuration Values

Key Value
Firebase Project fluid-isotope-89508
Firebase App ID 1:753481756590:android:5f4d78b68d1cf84d
Google Maps Key AIzaSyDZdBjmyHEMg20XUJJjR7l9pl2L4G4DP7E
Auth0 Domain login.coop.no
OIDC Well-known https://login.coop.no/.well-known/openid-configuration

Security Notes

  • Flutter app — SSL pinning likely in compiled Dart layer (libflutter.so)
  • Aera SDK handles SCA for payments (BankID + biometric)
  • No cert pinning in native Java/Kotlin layer
  • flutter_appauth used for OIDC flow
  • flutter_secure_storage for token persistence

Trumf / NorgesGruppen API

Trumf is the loyalty program for NorgesGruppen (Kiwi, Meny, Spar, Joker).

Authentication

Phone number + password → Bearer token
Platform: https://platform-rest-prod.ngdata.no/trumf/

Endpoints

Method Endpoint Description
GET /trumf/husstand/transaksjoner?felter=&fra=&til=&format= List transactions
GET /trumf/husstand/transaksjoner/detaljer/{batchid} Line item details

Transaction Fields

dato, beskrivelse, kjedeid, partnerid, batchid,
belop, trumf, ekstratrumf, trumfvisa, literbensin, trumftotal

Line Item Fields

varelinjer[] → vareTekst, ean, antall, belop

Existing Implementation

See ttyridal/trumf-data-fetch — a working Python script that fetches transactions and line items.


How This Was Done

Tools

Tool Purpose
jadx Decompile Android APK to Java/Kotlin source
apktool Decode APK resources and manifest
strings (GNU) Extract readable strings from compiled binaries
APKPure / apkeep Download APKs
Frida Dynamic instrumentation for SSL bypass
mitmproxy HTTPS traffic interception

Methodology

Step 1: Download APKs

# Using apkeep
apkeep -a no.rema.bella -d apk-pure ./output/

# Or download XAPK from APKPure
curl -L -o app.xapk "https://d.apkpure.net/b/XAPK/no.coop.members?version=latest"
unzip app.xapk -d extracted/

Step 2: Decompile (Native Kotlin — Rema)

jadx -d decompiled/ rema.apk
# Browse: decompiled/sources/no/shortcut/bella/data/remote/api/

Rema uses Retrofit2 with clean interface definitions — every endpoint is clearly annotated:

@GET("v1/bella/transaction/v2/heads")
suspend fun getTransactionHeads(): TransactionHeadsResponse

@GET("v1/bella/transaction/v2/rows/{tid}")
suspend fun getTransactionRows(@Path("tid") tid: Long): List<TransactionRow>

Step 3: Extract Strings (Flutter — Coop)

Flutter compiles Dart to native ARM code in libapp.so. It can't be decompiled to readable Dart, but string literals survive:

# Extract from XAPK split APK
unzip config.armeabi_v7a.apk "lib/armeabi-v7a/libapp.so"

# Find all URLs
strings libapp.so | grep -E "^https?://" | sort -u

# Find API paths
strings libapp.so | grep -E "^/user/" | sort -u

# Find data model class names
strings libapp.so | grep -E "^TPurchase" | sort -u

# Find JSON field names
strings libapp.so | grep -E "^(purchaseDate|receiptId|storeName|ean13)" | sort -u

# Find gRPC service paths
strings libapp.so | grep -E "^/coopnorge\." | sort -u

Step 4: Verify Authentication Config

# Fetch OIDC well-known (works without auth)
curl -s https://login.coop.no/.well-known/openid-configuration | jq

Step 5: Dynamic Interception (Optional)

For verifying request/response formats, use Frida + mitmproxy:

# Start mitmproxy
mitmdump --mode regular -p 8080 --ssl-insecure

# Launch app with Frida SSL bypass
frida -U -f no.rema.bella -l ssl-bypass.js --no-pause

Rema has no certificate pinning — standard mitmproxy works.
Coop is Flutter — needs Flutter-specific TLS bypass.


Existing Open Source

Repo Language Chain Description
Starefossen/node-rema-ae-api Node.js Rema 1000 API wrapper with Swagger spec
ttyridal/trumf-data-fetch Python Trumf Transaction + line item fetcher
wulffern/remaquery Python Rema 1000 Query exported data
okanten/norgesgruppen-api-wrapper Python NorgesGruppen Product search API
coopnorge (org) Various Coop Official infra tools (no receipt API)

Legal & Ethical Notes

  • Only access your own data — don't scrape other people's accounts
  • GDPR Article 15 gives you the right to access your personal data
  • ⚠️ These are private APIs — they may break without notice
  • ⚠️ Respect rate limits — don't hammer the endpoints
  • ⚠️ Norwegian grocery data may be PSD2-regulated if linked to payment instruments
  • Don't redistribute credentials, tokens, or other people's data

Created by Helge Sverre — February 2026

{
"openapi": "3.1.0",
"info": {
"title": "Rema 1000 Æ API",
"version": "3.0.12",
"description": "Reverse-engineered API specification for the Rema 1000 \"Æ\" Android app (no.rema.bella v3.0.12). Extracted via jadx decompilation of the APK. This API powers Norway's Rema 1000 loyalty program including receipt history, offers, shopping lists, and Scan & Pay.\n\n**Authentication:** OAuth 2.0 Authorization Code with PKCE via https://id.rema.no/\n**Developer:** Shortcut AS (no.shortcut.bella)\n\n⚠️ This is an unofficial, reverse-engineered spec. Use responsibly for personal data access only.",
"contact": {
"name": "Helge Sverre",
"url": "https://helgesver.re"
},
"license": {
"name": "MIT"
}
},
"servers": [
{ "url": "https://api.rema.no", "description": "Production" }
],
"security": [{ "bearerAuth": [] }, { "apimKey": [] }],
"tags": [
{ "name": "Transactions", "description": "Purchase history and receipt data" },
{ "name": "Offers", "description": "Available offers and activation" },
{ "name": "Customer", "description": "Customer profile and preferences" },
{ "name": "Stores", "description": "Store lookup and geolocation" },
{ "name": "ShoppingList", "description": "Collaborative shopping lists" },
{ "name": "ScanAndPay", "description": "Datema Scan & Pay self-checkout" },
{ "name": "Cards", "description": "Payment cards and Vipps" },
{ "name": "Payment", "description": "Payment processing" },
{ "name": "Articles", "description": "Product/article lookup" },
{ "name": "GDPR", "description": "Data access and subject access requests" },
{ "name": "Identity", "description": "IDP user and consent management" }
],
"paths": {
"/v1/bella/transaction/v2/heads": {
"get": {
"tags": ["Transactions"],
"operationId": "getTransactionHeads",
"summary": "List all purchases/receipts",
"description": "Returns a list of all purchase transactions with totals. Each transaction includes store name, amount, date, and receipt number.",
"responses": {
"200": {
"description": "Purchase list",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/TransactionHeadsResponse" },
"example": {
"bonusTotal": 0,
"purchaseTotal": 1337.14,
"discountTotal": 666.14,
"transactions": [{
"purchaseDate": 1600695669000,
"storeId": "0000",
"amount": 249.90,
"storeName": "Rema 1000 Storgate",
"id": 11223344556,
"receiptNbr": "2009210000123123123123123"
}]
}
}
}
}
}
}
},
"/v1/bella/transaction/v2/rows/{tid}": {
"get": {
"tags": ["Transactions"],
"operationId": "getTransactionRows",
"summary": "Get line items for a transaction",
"description": "Returns detailed line-item data for a specific purchase, including product names, EAN barcodes, prices, quantities, and applied discounts.",
"parameters": [
{ "name": "tid", "in": "path", "required": true, "schema": { "type": "integer", "format": "int64" }, "description": "Transaction ID from the heads response" }
],
"responses": {
"200": {
"description": "Transaction line items",
"content": {
"application/json": {
"schema": { "type": "array", "items": { "$ref": "#/components/schemas/TransactionRow" } }
}
}
}
}
}
},
"/v1/bellanaveo/receipt/{receiptId}/{customerId}": {
"get": {
"tags": ["Transactions"],
"operationId": "getReceipt",
"summary": "Get a specific receipt",
"parameters": [
{ "name": "receiptId", "in": "path", "required": true, "schema": { "type": "string" } },
{ "name": "customerId", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "Receipt data" } }
}
},
"/v1/bella/offers/v2/available-offers/": {
"get": {
"tags": ["Offers"],
"operationId": "getAvailableOffers",
"summary": "Get available offers",
"responses": { "200": { "description": "List of available offers" } }
}
},
"/v1/bella/offers/activate": {
"post": {
"tags": ["Offers"],
"operationId": "activateOffers",
"summary": "Activate offers",
"responses": { "200": { "description": "Offers activated" } }
}
},
"/v1/bella/offers/v2/offer-group/findgroup/{code}": {
"get": {
"tags": ["Offers"],
"operationId": "getOfferGroup",
"summary": "Get group offers by code",
"parameters": [
{ "name": "code", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "Group offer details" } }
}
},
"/v1/bella/offers/v2/offer-group/{code}/activate": {
"post": {
"tags": ["Offers"],
"operationId": "activateOfferGroup",
"summary": "Activate a group offer",
"parameters": [
{ "name": "code", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "Group offer activated" } }
}
},
"/bella/v2/customers": {
"get": {
"tags": ["Customer"],
"operationId": "getCustomer",
"summary": "Get customer info",
"responses": { "200": { "description": "Customer profile data" } }
},
"put": {
"tags": ["Customer"],
"operationId": "updateCustomer",
"summary": "Update member profile",
"responses": { "200": { "description": "Customer updated" } }
}
},
"/v1/bella/customers/v2/minimal": {
"get": {
"tags": ["Customer"],
"operationId": "getCustomerMinimal",
"summary": "Get user preferences (minimal profile)",
"responses": { "200": { "description": "Minimal customer data" } }
}
},
"/v1/bella/customers/lottery": {
"get": {
"tags": ["Customer"],
"operationId": "getOfferCounters",
"summary": "Get offer/lottery counters",
"responses": { "200": { "description": "Offer counters" } }
}
},
"/v1/bella/customers/getConsentsAndCommunicationChoices": {
"get": {
"tags": ["Customer"],
"operationId": "getConsents",
"summary": "Get consents and communication choices",
"responses": { "200": { "description": "Consent data" } }
}
},
"/bella/v2/allergens/member": {
"get": {
"tags": ["Customer"],
"operationId": "getAllergens",
"summary": "Get member allergen preferences",
"responses": { "200": { "description": "Allergen data" } }
}
},
"/bella/v2/allergens/setAllergens": {
"put": {
"tags": ["Customer"],
"operationId": "setAllergens",
"summary": "Update allergen preferences",
"responses": { "200": { "description": "Allergens updated" } }
}
},
"/v1/bella/user": {
"delete": {
"tags": ["Customer"],
"operationId": "deleteUser",
"summary": "Delete user account",
"responses": { "200": { "description": "User deleted" } }
}
},
"/v1/bella/workplace/{id}": {
"get": {
"tags": ["Stores"],
"operationId": "getStore",
"summary": "Get store by ID",
"parameters": [
{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "Store details" } }
}
},
"/v1/bella/workplace/search/{query}": {
"get": {
"tags": ["Stores"],
"operationId": "searchStores",
"summary": "Search stores by name",
"parameters": [
{ "name": "query", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "Store search results" } }
}
},
"/v1/bella/api/Geolocation": {
"get": {
"tags": ["Stores"],
"operationId": "findNearbyStore",
"summary": "Find nearest store by coordinates",
"parameters": [
{ "name": "Latitude", "in": "query", "required": true, "schema": { "type": "number" } },
{ "name": "Longitude", "in": "query", "required": true, "schema": { "type": "number" } }
],
"responses": { "200": { "description": "Nearest store" } }
}
},
"/v1/storespublic/{id}": {
"get": {
"tags": ["Stores"],
"operationId": "getPublicStore",
"summary": "Get public store info (no auth required)",
"security": [],
"parameters": [
{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "Public store info" } }
}
},
"/shoppinglist/lists": {
"get": {
"tags": ["ShoppingList"],
"operationId": "getShoppingLists",
"summary": "Get all shopping lists",
"responses": { "200": { "description": "List of shopping lists" } }
}
},
"/shoppinglist/{listId}": {
"get": {
"tags": ["ShoppingList"],
"operationId": "getShoppingList",
"summary": "Get a single shopping list",
"parameters": [
{ "name": "listId", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "Shopping list details" } }
}
},
"/shoppinglist/events": {
"post": {
"tags": ["ShoppingList"],
"operationId": "postShoppingListEvent",
"summary": "Post shopping list event (add/remove/check items)",
"responses": { "200": { "description": "Event processed" } }
}
},
"/shoppinglist/generateLink": {
"post": {
"tags": ["ShoppingList"],
"operationId": "generateShareLink",
"summary": "Generate a sharing link for a shopping list",
"responses": { "200": { "description": "Share link generated" } }
}
},
"/articleSearch/v1/search": {
"get": {
"tags": ["Articles"],
"operationId": "searchArticles",
"summary": "Search for products/articles",
"parameters": [
{ "name": "q", "in": "query", "required": true, "schema": { "type": "string" } },
{ "name": "rows", "in": "query", "schema": { "type": "integer" } },
{ "name": "page", "in": "query", "schema": { "type": "integer" } },
{ "name": "storeId", "in": "query", "schema": { "type": "string" } }
],
"responses": { "200": { "description": "Search results" } }
}
},
"/v1/articles/gtin/{gtin}": {
"get": {
"tags": ["Articles"],
"operationId": "getArticleByGtin",
"summary": "Get article details by GTIN/EAN barcode",
"parameters": [
{ "name": "gtin", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "Article details" } }
}
},
"/v1/articles/gtins": {
"post": {
"tags": ["Articles"],
"operationId": "getArticleThumbnails",
"summary": "Get product thumbnails for multiple GTINs",
"responses": { "200": { "description": "Article thumbnails" } }
}
},
"/v1/bellashoppingtrip/Sites/{storeNumber}/ShoppingTrips": {
"post": {
"tags": ["ScanAndPay"],
"operationId": "createShoppingTrip",
"summary": "Start a Scan & Pay shopping trip",
"parameters": [
{ "name": "storeNumber", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": { "201": { "description": "Shopping trip created" } }
}
},
"/v1/bellashoppingtrip/Sites/{storeNumber}/ShoppingTrips/{tripId}/Items": {
"post": {
"tags": ["ScanAndPay"],
"operationId": "addItemToTrip",
"summary": "Add an item to the shopping trip cart",
"parameters": [
{ "name": "storeNumber", "in": "path", "required": true, "schema": { "type": "string" } },
{ "name": "tripId", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "Item added" } }
}
},
"/v1/bellashoppingtrip/Sites/{storeNumber}/ShoppingTrips/{tripId}/End": {
"put": {
"tags": ["ScanAndPay"],
"operationId": "endShoppingTrip",
"summary": "Finalize the shopping trip and proceed to payment",
"parameters": [
{ "name": "storeNumber", "in": "path", "required": true, "schema": { "type": "string" } },
{ "name": "tripId", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "Trip finalized" } }
}
},
"/v1/bellacards/list": {
"get": {
"tags": ["Cards"],
"operationId": "listCards",
"summary": "List payment cards",
"responses": { "200": { "description": "Card list" } }
}
},
"/v1/bellacards/vipps/accounts": {
"get": {
"tags": ["Cards"],
"operationId": "getVippsAccounts",
"summary": "Get linked Vipps accounts",
"responses": { "200": { "description": "Vipps accounts" } }
}
},
"/bellapayment/initiate/{cartId}": {
"post": {
"tags": ["Payment"],
"operationId": "initiatePayment",
"summary": "Initiate a payment for a cart",
"parameters": [
{ "name": "cartId", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "Payment initiated" } }
}
},
"/bellapayment/status/{cartId}": {
"get": {
"tags": ["Payment"],
"operationId": "getPaymentStatus",
"summary": "Check payment status",
"parameters": [
{ "name": "cartId", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "Payment status" } }
}
},
"/v1/sardar/DataAccessRequest": {
"get": {
"tags": ["GDPR"],
"operationId": "getDataAccessRequests",
"summary": "Get data access requests (GDPR Art. 15)",
"responses": { "200": { "description": "Data access requests" } }
},
"post": {
"tags": ["GDPR"],
"operationId": "createDataAccessRequest",
"summary": "Submit a GDPR data access request",
"responses": { "200": { "description": "Request submitted" } }
}
},
"/v1/sardar/SubjectAccessRequest": {
"get": {
"tags": ["GDPR"],
"operationId": "getSubjectAccessRequests",
"summary": "Get subject access requests",
"responses": { "200": { "description": "Subject access requests" } }
},
"post": {
"tags": ["GDPR"],
"operationId": "createSubjectAccessRequest",
"summary": "Submit a subject access request",
"responses": { "200": { "description": "Request submitted" } }
}
}
},
"components": {
"securitySchemes": {
"bearerAuth": {
"type": "http",
"scheme": "bearer",
"bearerFormat": "JWT",
"description": "OAuth 2.0 access token from https://id.rema.no/token"
},
"apimKey": {
"type": "apiKey",
"in": "header",
"name": "ocp-apim-subscription-key",
"description": "Azure API Management subscription key"
}
},
"schemas": {
"TransactionHeadsResponse": {
"type": "object",
"properties": {
"bonusTotal": { "type": "number", "description": "Total bonus earned" },
"purchaseTotal": { "type": "number", "description": "Total purchase amount" },
"discountTotal": { "type": "number", "description": "Total discounts applied" },
"transactions": {
"type": "array",
"items": { "$ref": "#/components/schemas/Transaction" }
}
}
},
"Transaction": {
"type": "object",
"properties": {
"id": { "type": "integer", "format": "int64", "description": "Unique transaction ID" },
"purchaseDate": { "type": "integer", "format": "int64", "description": "Unix timestamp in milliseconds" },
"storeId": { "type": "string", "description": "Store identifier" },
"storeName": { "type": "string", "description": "Human-readable store name" },
"amount": { "type": "number", "description": "Total purchase amount in NOK" },
"receiptNbr": { "type": "string", "description": "Receipt number" }
}
},
"TransactionRow": {
"type": "object",
"description": "A single line item on a receipt",
"properties": {
"prodtxt1": { "type": "string", "description": "Product name (primary)" },
"prodtxt2": { "type": "string", "description": "Product name (secondary/variant)" },
"prodtxt3": { "type": "string", "description": "EAN barcode number" },
"productCode": { "type": "string", "description": "Internal product code" },
"productDescription": { "type": "string", "description": "Full product description" },
"productGroupDescription": { "type": "string", "description": "Product category" },
"unitPrice": { "type": "number", "description": "Price per unit in NOK" },
"amount": { "type": "number", "description": "Total line amount in NOK" },
"discount": { "type": "number", "description": "Discount applied in NOK" },
"usedOffers": { "type": "array", "items": { "type": "object" }, "description": "Offers applied to this item" }
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment