Skip to content

Latest commit

 

History

History
1292 lines (1059 loc) · 31.6 KB

File metadata and controls

1292 lines (1059 loc) · 31.6 KB

REMA 1000 API Documentation

Documented from the REMA-appen (Bella) iOS app v3.13.0.1181, captured 2026-04-06.

Base URL: https://api.rema.no

Authentication

All authenticated endpoints use Firebase JWT tokens issued by idp-rema (Google Secure Token).

Authorization: Bearer <firebase-jwt>

The JWT contains claims: cid (customer ID), client, user_id, phone_number, and standard Firebase fields.

Common Headers

Every request from the app includes these headers:

Header Description Example Value
Ocp-Apim-Subscription-Key Azure API Management subscription key (varies by API group) See per-endpoint
X-App App identifier Bella
X-Platform Client platform iOS
X-App-Version App version 3.13.0.1181
X-Device-ID Unique device identifier (UUID) 52A26EC5-1CCC-4009-ACE4-BD99CF6E91CD
X-Mobile-NR User's phone number (E.164) +4748248091
X-Correlation-ID Request trace ID (UUID) B5E65001-E319-4DF4-A87B-D50250353E52
Accept-Language Language preference no
User-Agent iOS CFNetwork user-agent REMA-appen/1181 CFNetwork/3860.400.51 Darwin/25.3.0

Subscription Keys (per API group)

API Group Key
Bella, Shopping List, Article Search, Analytics fb5e24884b504d0bad761098f77e6605
Papirfly Campaign e8494ceb23754fc4911c81b166e0a97f
Papirfly Product Images 409c75b6cc0741fc98d4c1e978ed3a38
Stores Public d5badff9cde84923a49b4906bd2f1509

1. App Version Check

Check minimum supported app versions and maintenance status.

GET /v1/bella/version

Auth required: No

Response 200:

{
  "service": {
    "maintenance": false,
    "description": "Denne app-versjonen støttes ikke lenger og du må oppdatere den."
  },
  "versions": {
    "ios": { "minVersion": "3.0.1" },
    "android": { "minVersion": "3.0.0" }
  },
  "versionsPriceCut": {
    "ios": { "minVersion": "3.0.1" },
    "android": { "minVersion": "3.0.0" }
  }
}

2. Customer Profile (Full)

Retrieve the full customer/member profile including bonus balance, segment, account details.

GET /bella/v2/customers

Auth required: Yes

Response 200:

{
  "member": {
    "id": 12065196856,
    "created": "2020-12-11T10:35:00.113+01:00",
    "modified": "2026-04-06T15:38:43.653+02:00",
    "createdBy": "Support (Abalon)",
    "modifiedBy": "Dev tusen",
    "accountNumber": "12415575",
    "lastPurchaseDate": "2022-07-23T18:31:59.677+02:00",
    "accBonusBalance": 0,
    "accBonusBalanceDecimal": 0.0,
    "bonusBalance": 0,
    "bonusBalanceDecimal": 0.0,
    "entryDate": "2020-12-11T10:35:00.113+01:00",
    "mainMember": {
      "name": "Home Unknown",
      "number": "12413523",
      "gender": "MALE",
      "mainMember": true,
      "age": 32,
      "firstName": "Home",
      "birthdate": "1991-10-02T01:00:00.000+01:00",
      "zipcode": "7033",
      "mobile": "004748248091",
      "personsInHousehold": 3,
      "guid": "c6ee82e3-5c9c-4de6-9409-36dc02aac698",
      "member": true,
      "communicationChoices": []
    },
    "segment": {
      "field": "0",
      "orgId": 0,
      "code": "2",
      "desc": "Kvalitet",
      "properties": "00",
      "id": 1002,
      "created": "2021-01-22T14:36:59.407+01:00",
      "modified": "2021-07-06T12:09:08.150+02:00",
      "createdBy": "Tommy",
      "modifiedBy": "Support (Extenda CCA)"
    },
    "segmentDate": "2023-02-03T23:13:19.187+01:00",
    "accountType": {
      "id": 222612,
      "properties": "00",
      "code": "M",
      "desc": "Medlem"
    },
    "lastTransaction": 1001414032394,
    "spennUser": false,
    "inRelationsHub": false
  },
  "primaryStoreNumber": "3198",
  "currencyCode": "NOK"
}

3. Customer Profile (Minimal)

Lightweight endpoint returning only bonus balance, primary store ID, and main member reference.

GET /v1/bella/customers/v2/minimal

Auth required: Yes

Response 200:

{
  "bonusBalance": 0,
  "bonusBalanceDecimal": 0,
  "primaryStore": "1011141087892",
  "mainMember": 12065196858
}

4. Update Customer Profile

Update mutable customer fields. Observed used to set the home store.

PUT /v1/bella/customer

Auth required: Yes
Additional headers: Upload-Draft-Interop-Version: 6, Upload-Complete: ?1

Request body:

{
  "homeworkplace": 1011141087892
}

Response 200: Full customer profile (same schema as GET /bella/v2/customers).


5. Available Offers

Retrieve all available offers, missions (bonus challenges), non-activated personal price cuts, and offer group headers for the authenticated user.

GET /v1/bella/offers/v2/available-offers

Auth required: Yes

Response 200:

{
  "offers": [
    {
      "id": 1007947235597,
      "code": "6000740",
      "desc": "10% Bonus på frukt- og grønnsaker",
      "start": 1738540800000,
      "stop": 2524518000000,
      "checkOffer": false,
      "note": "Les mer her",
      "dutyText": "https://...image-url...",
      "internalDescription": "Full description of the offer...",
      "combinable": true,
      "alwaysDisplay": false,
      "preselected": false,
      "activator": "6000740",
      "unlimitedUses": true,
      "memberOffer": false,
      "type": {
        "code": "def",
        "desc": "Default"
      },
      "header": 1008595570644,
      "priority": 5,
      "numberOfUsages": 0,
      "activated": false,
      "value": null,
      "unit": null,
      "txt": null,
      "buttonText": null,
      "marketingUrl": null
    }
  ],
  "headers": [
    {
      "id": 1002048697053,
      "title": "KONKURRANSE",
      "priority": 1,
      "code": "1251",
      "desc": "KONKURRANSE",
      "alignHorizontal": false
    }
  ],
  "offerGroups": [],
  "nonactivatedoffers": [
    {
      "code": "31315382",
      "desc": "Alle R fryste grønnsaker",
      "value": 20.0,
      "start": 1775340000000,
      "stop": 1775944799000
    }
  ],
  "missions": [
    {
      "code": "6001086",
      "desc": "Bonusoppdrag SP3 Husvask og kluter - Kjøp 4 tjen 40% Bonus",
      "offer": 1011308931085,
      "completed": "0",
      "nbrofusages": "0",
      "remaining_usages": "4"
    }
  ]
}

Offer Type Codes

Code Description
def Default / informational offer
pointConfig Point/bonus calculation configuration (bonus missions)
lottery Lottery / competition

6. Customer Lottery

Get active lotteries and the user's ticket count.

GET /v1/bella/customers/lottery

Auth required: Yes

Response 200:

[
  {
    "numberOfTickets": 0,
    "lotteryConfiguration": {
      "id": 1011663215165,
      "code": "6001110",
      "offer": {
        "id": 1011663215136,
        "code": "6001110",
        "desc": "Vinn billetter til UEFA WOMENS CHAMPIONS LEAGUE FINALEN i Oslo!",
        "note": "Les mer om hvordan du deltar her",
        "dutyText": "https://...image-url...",
        "internalDescription": "Full lottery description...",
        "activator": "6001110",
        "marketingUrl": "https://www.rema.no/...",
        "buttonText": "Se konkurransevilkår her",
        "read": false
      },
      "hideLottery": false
    }
  }
]

7. Member Allergens

Get the member's registered allergens for the allergen scanner feature.

GET /bella/v2/allergens/member

Auth required: Yes

Response 200:

{
  "accountNumber": "12415575",
  "allergens": []
}

8. Campaigns (Papirfly)

Retrieve sales campaigns with full product offer details. Used for the weekly flyer / "Superpriser" feature.

GET /v1/papirflycampaign/campaigns?type=SP&includeOffers=true&feed=true

Auth required: Yes
Subscription Key: e8494ceb23754fc4911c81b166e0a97f (different from other endpoints)

Query Parameters

Parameter Type Description
type string Campaign type filter (e.g. SP for Superpriser)
includeOffers boolean Include full offer/product details
feed boolean Include feed data

Response 200:

[
  {
    "campaignId": 342,
    "publication": "2026 SP4 - uke 15-17",
    "createdDate": "2025-07-31T07:03:56.517+02:00",
    "modifiedDate": "2026-02-11T10:05:47.223+01:00",
    "validFrom": "2026-04-06T00:00:00+02:00",
    "validTo": "2026-04-26T00:00:00+02:00",
    "firstPeriodEnd": "1753-01-01T00:00:00",
    "secondPeriodEnd": "1753-01-01T00:00:00",
    "active": true,
    "type": ["SP"],
    "region": [
      {
        "remaId": "6",
        "regionName": "REMA 1000 Norge AS"
      }
    ],
    "disclaimerText": [
      {
        "remaId": "6",
        "disclaimerText": "Vi tar forbehold om skrivefeil..."
      }
    ],
    "offers": {
      "offers": [
        {
          "title": "TORTILLA THIN 6PK",
          "undertekst": "OLD EL PASO, 192 G, 137,19 PR. KG",
          "prisKroner": "26",
          "prisOerer": "34",
          "prisEnhet": "",
          "beforePrice": 43.9,
          "impact": "C",
          "spydspiss": false,
          "cohort": "TEX MEX",
          "harPant": false,
          "hasBeforePrice": true,
          "validDates": [
            {
              "from": "2026-04-06T00:00:00+02:00",
              "to": "2026-04-26T00:00:00+02:00"
            }
          ],
          "sammensattProduct": false,
          "mekanismeDeal": "",
          "mekanismeOblat": "",
          "mekanismePriskonsept": "",
          "mekanismePrisboks": "Førpris",
          "mekanismeSnakkeboble": "",
          "mekanismeProsent": 0,
          "UseInDM": true,
          "products": [
            {
              "epd": "6111306",
              "productSupplier": "HAUGEN-GRUPPEN AS",
              "productName": "TORTILLAS EXTRA THIN 192G OLD EL PASO",
              "gtin": ["8410076475541"],
              "productId": 89699,
              "imageUrl": "https://rema.papirfly.no/readimage.aspx/asset.png?pubid=...&quality=3"
            }
          ],
          "productId": 89699,
          "imageUrl": "https://rema.papirfly.no/readimage.aspx/asset.png?pubid=...&quality=3"
        }
      ]
    }
  }
]

Campaign Offer Fields

Field Description
prisKroner / prisOerer Sale price in kroner and oere
beforePrice Original price before discount
impact Display impact level (A, B, C)
spydspiss Whether this is a "spearhead" / flagship deal
cohort Product category grouping
harPant Whether the product has a bottle deposit (pant)
mekanismePrisboks Price display mechanism (e.g. Førpris = "was price")
sammensattProduct Whether this is a composite/bundle product
products[].gtin GTIN barcodes for the product
products[].epd Internal EPD product number

9. Article Search

Search for products/articles. Used for shopping list autocomplete.

GET /articlesearch/v1/search?q={query}&rows={limit}

Auth required: Yes

Query Parameters

Parameter Type Description
q string Search query (supports incremental/typeahead)
rows integer Maximum number of results to return

Response 200:

{
  "metadata": {
    "indexVersion": "article-search-v7-3-hybrid",
    "searchInsightId": "1a7c8ac3-0250-434b-86b0-c3c09d6f7304"
  },
  "value": [
    {
      "remaID": 10126111,
      "gtin": 7057370030369,
      "SearchScore": 0.08058023,
      "salesvariantNumber": 2,
      "salesVariantDescription": "Kyllingfilet Strimlet 450G Solvinge",
      "merchStructureNameLevel4": "KYLLING RENT",
      "merchStructureIDLevel2": 11,
      "merchStructureIDLevel3": 1113,
      "merchStructureIDLevel4": 111310,
      "compareConversionFactor": 0.45,
      "comparisonUnit": "KG",
      "packingSize": "450 G"
    }
  ]
}

Article Search Fields

Field Description
remaID Internal REMA product ID
gtin Global Trade Item Number (barcode)
SearchScore Relevance score
salesvariantNumber Sales variant identifier
salesVariantDescription Display name with size
merchStructureNameLevel4 Product category name
merchStructureIDLevel2-4 Category hierarchy IDs (department > group > subgroup)
compareConversionFactor Unit conversion factor for price comparison
comparisonUnit Comparison unit (KG, L, STK)
packingSize Package size description

The metadata.searchInsightId is passed back as searchInsightId in the AddItem event when an item is added from a search result.


10. Product Images

Retrieve product images by GTIN barcode.

GET /papirfly/getproductimg?gtin={gtin}&quality={quality}&webpformat={webpformat}

Auth required: Yes
Subscription Key: 409c75b6cc0741fc98d4c1e978ed3a38

Query Parameters

Parameter Type Description
gtin string Product GTIN/barcode
quality integer Image quality level: 1 = thumbnail, 2 = higher resolution
webpformat boolean Return WebP format when true

Response 200: Binary image data (WebP or PNG)


11. Store by ID

Get a single store's details by its internal workplace ID.

GET /v1/bella/workplace/{workplaceId}

Auth required: Yes

Path parameters:

Parameter Description
workplaceId Internal workplace ID (e.g. 1011141087892)

Response 200:

{
  "id": 1011141087892,
  "name": "REMA 1000 NARDOCENTERET",
  "number": "3198",
  "openingHoursWeekdays": "07:00:00-23:00:00",
  "openingHoursSaturdays": "07:00:00-23:00:00",
  "openingHoursSundays": "Stengt",
  "street": "Hans Baucks veg 1",
  "zipCode": "7033",
  "city": "TRONDHEIM",
  "closeDate": "2049-12-31T01:00:00.000+01:00",
  "openingDate": "2026-03-19T01:00:00.000+01:00",
  "openingHoursToday": "Stengt",
  "openingHourDeviations": [
    {
      "openingHoursDate": "2026-04-06",
      "status": "X:ClosedException"
    },
    {
      "openingHoursDate": "2026-05-23",
      "openingTime": "07:00:00",
      "closingTime": "16:00:00",
      "status": "Open"
    }
  ]
}

Opening Hour Deviation Status Values

Status Meaning
Open Store open with specific hours that day
Closed Store closed that day
X:ClosedException Store closed due to a public holiday

12. Store Search

Search for stores by zipcode, store number, or name fragment.

GET /v1/bella/workplace/search/{query}

Auth required: Yes

Path parameters:

Parameter Description
query Search string — zipcode, store number, or partial name

Response 200: Array of store objects (same schema as GET /v1/bella/workplace/{workplaceId}, minus street/zipCode/city/closeDate/openingDate). Returns an empty body (200 with 0 bytes) if no matches.

[
  {
    "id": 1011141087892,
    "name": "REMA 1000 NARDOCENTERET",
    "number": "3198",
    "openingHoursWeekdays": "07:00:00-23:00:00",
    "openingHoursSaturdays": "07:00:00-23:00:00",
    "openingHoursSundays": "Stengt",
    "openingHoursToday": "Stengt",
    "openingHourDeviations": [...]
  }
]

13. Store Opening Hours (This Week)

Get the opening hours schedule for a store for the current week, grouped by day.

GET /v1/storespublic/{storeNumber}/opening_hours_daily/this_week

Auth required: Yes
Subscription Key: d5badff9cde84923a49b4906bd2f1509

Path parameters:

Parameter Description
storeNumber Store number (e.g. 3198) — this is the short number field, not the workplace ID

Response 200:

{
  "StoreId": "3198",
  "StartOfWeek": "2026-04-06T00:00:00",
  "OpeningHours": [
    {
      "dayOfWeek": ["Monday"],
      "Opens": "00:00",
      "Closes": "00:00"
    },
    {
      "dayOfWeek": ["Sunday"],
      "Opens": "00:00",
      "Closes": "00:00"
    },
    {
      "dayOfWeek": ["Tuesday", "Wednesday", "Thursday", "Friday"],
      "Opens": "07:00",
      "Closes": "23:00"
    },
    {
      "dayOfWeek": ["Saturday"],
      "Opens": "07:00",
      "Closes": "23:00"
    }
  ]
}

Days with "Opens": "00:00" and "Closes": "00:00" are closed. Multiple days with the same hours are grouped into a single entry.


14. Transaction History

Transaction Headers

Get the user's purchase transaction headers and bonus/discount totals.

GET /v1/bella/transaction/v2/heads

Auth required: Yes

Response 200:

{
  "bonusTotal": 0,
  "bonusTotalDecimal": 0,
  "purchaseTotal": 0.0,
  "discountTotal": 0.0,
  "transactions": []
}

Transaction Line Items

Get line items (products purchased) and payment breakdown for a single transaction.

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

Auth required: Yes

Path Parameters

Parameter Type Description
transactionId integer Transaction ID. Obtained from member.lastTransaction on GET /bella/v2/customers, or from an entry in GET /v1/bella/transaction/v2/heads.

Response 200:

{
  "bonusPointsTotal": 115,
  "bonusPointsTotalDecimal": 115.82,
  "bonusPointsBasedOnReceipt": 0,
  "rows": [
    {
      "productCode": "10103680002",
      "productDescription": "COCA-COLA UTEN SUKKER 1.5L 4PK",
      "prodtxt1": "Coca-Cola Uten Sukker 1.5L 4Pk",
      "prodtxt2": "4X1,5 L 4Pk",
      "prodtxt3": "7090000248123",
      "productGroupCode": "151010",
      "productGroupDescription": "BRUS (STOR)",
      "bonusBased": true,
      "pieces": 1,
      "amount": 91.9,
      "amountWithoutDeposit": 79.9,
      "discount": 0.0,
      "volume": 1.0,
      "unit": "EA",
      "deposit": 12.0,
      "unitPrice": 91.9,
      "bonusPoints": 0,
      "bonusPointsDecimal": 0
    }
  ],
  "transactionPayments": [
    { "meansOfPaymentDesc": "Rounding", "amount": 0.0 },
    { "meansOfPaymentDesc": "CreditDebit", "amount": 1147.49 }
  ]
}

Row Fields

Field Type Description
productCode string Internal SKU
productDescription string Upper-case description from till receipt
prodtxt1prodtxt3 string Optional display text; prodtxt3 is the GTIN when known
productGroupCode / productGroupDescription string Product category
bonusBased bool Whether the row earns bonus
pieces number Count of discrete items
amount number Charged amount including deposit (NOK)
amountWithoutDeposit number Charged amount excluding deposit
discount number Discount applied (NOK)
volume number Quantity in unit (weight for Kg, else 1.0)
unit string EA for each-sold items, Kg for weight-sold
deposit number Pant/deposit (NOK)
unitPrice number Price per unit
bonusPoints / bonusPointsDecimal number Bonus earned on this row

transactionPayments[*].meansOfPaymentDesc observed values: Rounding, CreditDebit.


15. Campaign State Update

Signal to the server that the user has opened the discounts/campaign view.

PUT /v1/bella/campaign?discountsOpen=true

Auth required: Yes
Request body: empty (Content-Length: 0)

Query Parameters

Parameter Type Description
discountsOpen boolean Set to true when the user opens the discounts tab

Response 200: Empty body


16. Communication Choice (Scan & Go)

Check whether the user has accepted the Scan & Go communication choice.

GET /v1/bella/communication/communicationChoices/scanAndGo/scanAndGo

Auth required: Yes

Response 200: A single JSON boolean value.

false

17. Consent by Type Code

Check whether the user has given consent for a specific consent type.

GET /v1/bella/consent/typecode?consentTypeCode={code}

Auth required: Yes

Query Parameters

Parameter Type Description
consentTypeCode string Consent type identifier (e.g. birthdate)

Response 200: Consent details (schema not observed — only 404 responses captured).
Response 404: Consent record does not exist for this user.


18. Shopping Lists

List All Shopping Lists

GET /shoppinglist/lists

Auth required: Yes

Response 200:

[
  {
    "listId": "29D9D5F0-99C0-4EA4-9452-ED1D5F95AC6C",
    "listName": "Hu",
    "createdAt": "2026-04-06T12:03:14.9690223Z",
    "updatedAt": "2026-04-06T13:11:25Z",
    "emoji": "🍳",
    "theme": "BLUE",
    "image": "",
    "description": "",
    "numberOfItems": 2,
    "userRole": "Owner"
  },
  {
    "listId": "C5EA5161-E6C1-4249-A6D2-B6EE28668F78",
    "listName": "Nomnom",
    "createdAt": "2026-03-19T16:25:44.2104178Z",
    "updatedAt": "2026-03-28T21:42:18Z",
    "emoji": "🛒",
    "theme": "PURPLE",
    "image": "",
    "description": "",
    "numberOfItems": 0,
    "userRole": "Contributor"
  }
]

userRole is "Owner" for lists the user created or "Contributor" for shared lists.


Get Shopping List

GET /shoppinglist/{listId}

Auth required: Yes

Response 200:

{
  "listId": "29D9D5F0-99C0-4EA4-9452-ED1D5F95AC6C",
  "listName": "Hu",
  "createdAt": "2026-04-06T12:03:14.9690223Z",
  "updatedAt": "2026-04-06T13:11:25Z",
  "emoji": "🍳",
  "theme": "BLUE",
  "image": "",
  "description": "",
  "myShoppingListUserId": "155229dd-c2b5-454f-ad4b-19346231c39b",
  "users": [
    {
      "shoppingListUserId": "155229dd-c2b5-454f-ad4b-19346231c39b",
      "role": "Owner",
      "profileDataTimestamp": "2026-03-20T10:53:58.4787486Z"
    }
  ],
  "items": [
    {
      "itemId": "010D5219-76A6-41FD-8240-2425AF38BF4C",
      "itemName": "Kyllingkjøttdeig 400G Solvinge",
      "description": "400 G",
      "gtin": "7057370030079",
      "quantity": 1,
      "state": "Active",
      "comment": "400 G",
      "category": "",
      "updatedAt": "2026-04-06T13:11:08.237Z",
      "storeArea": 11,
      "nextItem": "ACA0B3DA-2F60-4FE9-B300-70DBDC16EEB1"
    },
    {
      "itemId": "ACA0B3DA-2F60-4FE9-B300-70DBDC16EEB1",
      "itemName": "Hehe",
      "description": "",
      "gtin": "",
      "quantity": 1,
      "state": "Active",
      "comment": "",
      "category": "",
      "updatedAt": "2026-04-06T13:11:21.406Z",
      "nextItem": ""
    }
  ]
}

Items are sorted by nextItem pointer (linked list). The last item has nextItem: "".

Shopping List Item Fields

Field Description
itemId Client-generated UUID for the item
itemName Display name
gtin Product barcode (empty for freetext items)
storeArea In-store department/area code (0 if unknown)
description / comment Package size or note
state "Active" (visible) or "Inactive" (checked off)
quantity Item quantity
nextItem UUID of the next item in display order (linked list), "" for last item

Shopping List Events

All mutations (create/delete lists, add/update/delete items) go through a single event endpoint.

POST /shoppinglist/events

Auth required: Yes
Additional headers: Upload-Draft-Interop-Version: 6, Upload-Complete: ?1

All events share this envelope:

{
  "data": {
    "action": "<ActionName>",
    ...action-specific fields...
  },
  "metadata": {
    "copyToOthers": true,
    "source": "App",
    "version": "1.0"
  },
  "timestamp": 1775483904294
}

timestamp is Unix epoch milliseconds. copyToOthers: true propagates the change to other list members.

Response 200:

{
  "action": "AddItem",
  "listId": "29D9D5F0-99C0-4EA4-9452-ED1D5F95AC6C",
  "message": "Event AddItem was performed successfully for list id 29D9D5F0-99C0-4EA4-9452-ED1D5F95AC6C"
}

Response 400: The item referenced in the event does not exist in the list (e.g. DeleteItem on a non-existent item).

CreateList

{
  "data": {
    "action": "CreateList",
    "list": {
      "description": "",
      "emoji": "☕️",
      "name": "New list",
      "theme": "RED",
      "image": ""
    },
    "listId": "27D3803E-F2EE-459F-BC20-260A4C1B8A88"
  },
  ...
}

listId is a client-generated UUID. theme values observed: RED, BLUE, PURPLE.

To set a custom list image, pass the image as a base64-encoded JPEG string in list.image. When an image is provided, name and emoji can be empty strings. The encoded image is embedded directly in the JSON body — a full-resolution photo produces a request body of ~1.6 MB. Omit the field or pass "" to create a list without an image.

DeleteList

{
  "data": {
    "action": "DeleteList",
    "listId": "29D9D5F0-99C0-4EA4-9452-ED1D5F95AC6C"
  },
  ...
}

AddItem (from search result)

{
  "data": {
    "action": "AddItem",
    "item": {
      "category": "",
      "comment": "1000 G",
      "description": "1000 G",
      "gtin": "7057370030475",
      "itemId": "5DFB3680-5921-491E-8515-B1EE351AA9DF",
      "itemName": "Kyllingfilet Naturell 1000G Solvinge",
      "quantity": 1,
      "state": "Active",
      "storeArea": 11,
      "updatedAt": "2026-04-06T13:58:36.415Z"
    },
    "listId": "29D9D5F0-99C0-4EA4-9452-ED1D5F95AC6C"
  },
  "metadata": {
    "copyToOthers": true,
    "searchInsightId": "1a7c8ac3-0250-434b-86b0-c3c09d6f7304",
    "source": "App",
    "version": "1.0"
  },
  "timestamp": 1775483916415
}

When the item was added via product search, the metadata object includes searchInsightId from the article search response.

AddItem (freetext, no product match)

{
  "data": {
    "action": "AddItem",
    "item": {
      "category": "",
      "comment": "",
      "description": "",
      "gtin": "",
      "itemId": "ACA0B3DA-2F60-4FE9-B300-70DBDC16EEB1",
      "itemName": "Hehe",
      "quantity": 1,
      "state": "Active",
      "storeArea": 0,
      "updatedAt": "2026-04-06T13:11:21.406Z"
    },
    "listId": "29D9D5F0-99C0-4EA4-9452-ED1D5F95AC6C"
  },
  ...
}

UpdateItem

Used to check off an item (state: "Inactive") or uncheck it (state: "Active"), or to update quantity/name.

{
  "data": {
    "action": "UpdateItem",
    "item": {
      "category": "",
      "comment": "",
      "description": "400 G",
      "gtin": "7057370030079",
      "itemId": "010D5219-76A6-41FD-8240-2425AF38BF4C",
      "itemName": "Kyllingkjøttdeig 400G Solvinge",
      "quantity": 1,
      "state": "Inactive",
      "storeArea": 11,
      "updatedAt": "2026-04-06T13:58:24.295Z"
    },
    "listId": "29D9D5F0-99C0-4EA4-9452-ED1D5F95AC6C"
  },
  ...
}

DeleteItem

{
  "data": {
    "action": "DeleteItem",
    "item": {
      "category": "",
      "itemId": "B3AF366C-C210-4A36-80D3-A8CAFB994700",
      "itemName": "",
      "quantity": 1,
      "state": "Active",
      "updatedAt": "2026-04-06T13:59:05.529Z"
    },
    "listId": "29D9D5F0-99C0-4EA4-9452-ED1D5F95AC6C"
  },
  ...
}

Returns 400 if the item does not exist in the list.

DeleteInactiveItems

Remove all items currently in "Inactive" state (i.e. checked off items) at once.

{
  "data": {
    "action": "DeleteInactiveItems",
    "listId": "29D9D5F0-99C0-4EA4-9452-ED1D5F95AC6C"
  },
  ...
}

SetAllItemsActive

Uncheck all items on the list (reset all "Inactive" items back to "Active").

{
  "data": {
    "action": "SetAllItemsActive",
    "listId": "29D9D5F0-99C0-4EA4-9452-ED1D5F95AC6C"
  },
  ...
}

Generate Share Link

Create a time-limited invitation link for another user to join the list.

POST /shoppinglist/generatelink

Auth required: Yes
Additional headers: Upload-Draft-Interop-Version: 6, Upload-Complete: ?1

Request body:

{
  "invitationCreatedBy": "Home",
  "listId": "29D9D5F0-99C0-4EA4-9452-ED1D5F95AC6C"
}

Response 200:

{
  "hash": "kIGPYnx6",
  "link": "https://rema.no/app/handleliste?rslh=kIGPYnx6",
  "validTo": "2026-04-13T13:58:11.8314741Z"
}

The link is valid for 7 days. Opening it on a device with the app installed redirects to the in-app join flow.


Get List Image

Retrieve the custom image set for a shopping list.

GET /shoppinglist/image?listId={listId}

Auth required: Yes

Response 200: Binary image data.
Response 400: No image is set for this list.


Get User Profile Picture (for list)

Retrieve a collaborator's profile picture in the context of a shared list.

GET /shoppinglist/getProfilePicture?listId={listId}&shoppingListUserId={userId}&timestamp={timestamp}

Auth required: Yes

Query Parameters

Parameter Description
listId UUID of the shopping list
shoppingListUserId UUID of the list user (from users[].shoppingListUserId)
timestamp ISO 8601 timestamp (URL-encoded) — used as a cache-buster, typically the user's profileDataTimestamp

Response 200: Binary image data (15 bytes observed for users without a profile picture set).


19. Analytics

Log in-app analytics events (view impressions, interactions).

POST /bellaanalytics/analytics/logEvents

Auth required: Yes
Additional headers: Upload-Draft-Interop-Version: 6, Upload-Complete: ?1

Request body: Array of event objects.

[
  {
    "contentType": "Card",
    "eventName": "view_promotion",
    "itemCategory2": "Kun 199,- for KaffeAvtalen",
    "itemId": "6000990",
    "pseudoId": "52414806",
    "screenClass": "MainActivity",
    "screenName": "Home",
    "timestamp": "2026-04-06T15:57:55.4210000+02:00"
  }
]

Response 200:

{
  "status": "ok",
  "total": 1,
  "succeeded": 1,
  "failed": 0
}

API Endpoint Summary

# Method Path Auth Sub Key Description
1 GET /v1/bella/version No Bella App version & maintenance status
2 GET /bella/v2/customers Yes Bella Full customer profile
3 GET /v1/bella/customers/v2/minimal Yes Bella Bonus balance + primary store
4 PUT /v1/bella/customer Yes Bella Update customer profile (e.g. home store)
5 GET /v1/bella/offers/v2/available-offers Yes Bella Offers, missions, price cuts
6 GET /v1/bella/customers/lottery Yes Bella Active lotteries & ticket count
7 GET /bella/v2/allergens/member Yes Bella Member allergen preferences
8 GET /v1/papirflycampaign/campaigns Yes Papirfly Campaign Sales campaigns with products
9 GET /articlesearch/v1/search Yes Bella Product search (typeahead)
10 GET /papirfly/getproductimg Yes Papirfly Images Product image by GTIN
11 GET /v1/bella/workplace/{workplaceId} Yes Bella Store details by workplace ID
12 GET /v1/bella/workplace/search/{query} Yes Bella Store search by zipcode/number/name
13 GET /v1/storespublic/{storeNumber}/opening_hours_daily/this_week Yes Stores Public Weekly opening hours schedule
14 GET /v1/bella/transaction/v2/heads Yes Bella Transaction history headers
14b GET /v1/bella/transaction/v2/rows/{transactionId} Yes Bella Transaction line items + payments
15 PUT /v1/bella/campaign Yes Bella Signal discounts view opened
16 GET /v1/bella/communication/communicationChoices/scanAndGo/scanAndGo Yes Bella Scan & Go communication consent
17 GET /v1/bella/consent/typecode Yes Bella Consent status by type code
18 GET /shoppinglist/lists Yes Bella List all user's shopping lists
19 GET /shoppinglist/{listId} Yes Bella Get shopping list with items
20 POST /shoppinglist/events Yes Bella All shopping list mutations
21 POST /shoppinglist/generatelink Yes Bella Generate list share/invite link
22 GET /shoppinglist/image Yes Bella List custom image
23 GET /shoppinglist/getProfilePicture Yes Bella User profile picture for list
24 POST /bellaanalytics/analytics/logEvents Yes Bella Log analytics events