ShopList

API Reference

Programmatic access to ShopList — build bots, integrations, and automations.

Authentication

All requests require an API key via the X-API-Key header:

X-API-Key: YOUR_API_KEY

Most endpoints also need a user_id query parameter to identify the acting user. Contact the admin for your API key and user ID.

Base URL: https://shopping.sprcon.de/api/

Lists

GET /api/lists/?user_id={id}

Returns all shopping lists the user owns, is shared with, or belongs to via group.

{
  "lists": [
    {
      "id": 1,
      "name": "Weekly Groceries",
      "owner": 1,
      "group": null,
      "created_at": "2026-01-15T10:30:00Z",
      "items": [ ... ],
      "items_count": 5
    }
  ]
}

POST /api/lists/create/?user_id={id}

Create a new shopping list. Send a JSON body.

FieldTypeRequiredDescription
namestringyesList name (max 100 chars)
group_idintegernoGroup to associate list with
# Personal list
{ "name": "My Shopping List" }

# Group list
{ "name": "Family Groceries", "group_id": 2 }

Returns 201 Created with the list object. User must be member of specified group.

DELETE /api/lists/{id}/delete/?user_id={id}

Delete a personal list. Only the owner can delete, and only personal lists (no group).

{ "message": "List deleted successfully" }
Note: Cannot delete shared/group lists. Use the leave endpoint instead.

POST /api/lists/{id}/leave/?user_id={id}

Leave a shared or group list. Removes the user from the list.

  • If you're the owner, ownership transfers to another member
  • If no members remain, the list is deleted
  • Cannot leave personal lists (use delete instead)
# Success
{ "message": "Successfully left the list" }

# List deleted when no members remain
{ "message": "List deleted as no members remain" }

Items

GET /api/lists/{list_id}/items/?user_id={id}

Returns all items in a shopping list.

{
  "items": [
    {
      "id": 1,
      "shopping_list": 1,
      "name": "Milk",
      "category": { "id": 2, "name": "Dairy" },
      "amount": 2,
      "max_price": "3.50",
      "buy_until": "2026-02-15",
      "link": null,
      "created_at": "2026-02-10T14:00:00Z",
      "is_bought": false
    }
  ]
}

POST /api/lists/{list_id}/items/create/?user_id={id}

Add a new item to a list. Send a JSON body.

FieldTypeRequiredDescription
namestringyesItem name (max 100 chars)
amountintegernoQuantity (default: 1)
category_idintegernoCategory ID
max_pricedecimalnoMaximum price
buy_untilYYYY-MM-DDnoPurchase deadline
linkURLnoProduct link

Returns 201 Created with the item object.

PATCH /api/items/{item_id}/update/?user_id={id}

Update an item. Send only fields to change.

{ "amount": 3, "max_price": "4.00" }

DELETE /api/items/{item_id}/delete/?user_id={id}

Delete an item.

{ "message": "Item deleted successfully" }

POST /api/items/{item_id}/toggle/?user_id={id}

Toggle is_bought status. Returns the updated item.

Categories

GET /api/categories/

List all categories. No user_id required.

{
  "categories": [
    { "id": 1, "name": "Electronics" },
    { "id": 2, "name": "Groceries" },
    { "id": 3, "name": "Household" }
  ]
}

POST /api/categories/create/?user_id={id}

Create a new category. Send a JSON body.

FieldTypeRequiredDescription
namestringyesCategory name (must be unique)
{ "name": "Books" }

Returns 201 Created with the category object, or 400 if category already exists.

Shops

GET /api/shops/

List all shops and their categories. No user_id required.

{
  "shops": [
    {
      "id": 1,
      "name": "Amazon",
      "url": "https://amazon.de",
      "categories": [
        { "id": 1, "name": "Electronics" },
        { "id": 3, "name": "Household" }
      ]
    }
  ]
}

Groups

GET /api/groups/?user_id={id}

List all groups the user belongs to.

{
  "groups": [
    {
      "id": 1,
      "name": "Household",
      "members": [1, 2, 3],
      "created_at": "2026-01-01T00:00:00Z"
    }
  ]
}

Bulk Check

GET /api/bulk-check/?user_id={id}

Scans all unbought items across all accessible lists. Groups by category and returns categories with 2+ items — potential bulk order opportunities.

{
  "bulk_opportunities": {
    "Electronics": [
      { "id": 5, "name": "USB-C Cable", "list_name": "Office", "amount": 3, "max_price": "8.00" },
      { "id": 12, "name": "HDMI Adapter", "list_name": "Living Room", "amount": 1, "max_price": null }
    ]
  }
}

Errors

All errors return JSON with an error field:

StatusMeaning
400Bad request — missing params, invalid JSON
401Invalid or missing API key
403No access to this resource
404Not found
405Wrong HTTP method

Examples

curl

# List your shopping lists
curl -H "X-API-Key: YOUR_KEY" \
  "https://shopping.sprcon.de/api/lists/?user_id=1"

# Create a personal list
curl -X POST \
  -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "My New List"}' \
  "https://shopping.sprcon.de/api/lists/create/?user_id=1"

# Create a group list
curl -X POST \
  -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Family List", "group_id": 2}' \
  "https://shopping.sprcon.de/api/lists/create/?user_id=1"

# Leave a list
curl -X POST -H "X-API-Key: YOUR_KEY" \
  "https://shopping.sprcon.de/api/lists/3/leave/?user_id=1"

# Delete a personal list
curl -X DELETE -H "X-API-Key: YOUR_KEY" \
  "https://shopping.sprcon.de/api/lists/5/delete/?user_id=1"

# Add an item
curl -X POST \
  -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Bananas", "amount": 6}' \
  "https://shopping.sprcon.de/api/lists/1/items/create/?user_id=1"

# List categories
curl -H "X-API-Key: YOUR_KEY" \
  "https://shopping.sprcon.de/api/categories/"

# Create category
curl -X POST \
  -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Books"}' \
  "https://shopping.sprcon.de/api/categories/create/?user_id=1"

# Toggle bought
curl -X POST -H "X-API-Key: YOUR_KEY" \
  "https://shopping.sprcon.de/api/items/3/toggle/?user_id=1"

# Check bulk opportunities
curl -H "X-API-Key: YOUR_KEY" \
  "https://shopping.sprcon.de/api/bulk-check/?user_id=1"

Python

import requests

BASE = "https://shopping.sprcon.de/api"
HEADERS = {"X-API-Key": "YOUR_KEY"}
USER = {"user_id": "1"}

# Get all lists
lists = requests.get(f"{BASE}/lists/", headers=HEADERS, params=USER).json()

# Create a personal list
new_list = requests.post(
    f"{BASE}/lists/create/",
    headers={**HEADERS, "Content-Type": "application/json"},
    params=USER,
    json={"name": "My Shopping List"}
).json()

# Create a category
category = requests.post(
    f"{BASE}/categories/create/",
    headers={**HEADERS, "Content-Type": "application/json"},
    params=USER,
    json={"name": "Electronics"}
).json()

# Add an item
requests.post(
    f"{BASE}/lists/1/items/create/",
    headers={**HEADERS, "Content-Type": "application/json"},
    params=USER,
    json={"name": "Coffee", "amount": 1, "category_id": 3}
)

# Leave a list
requests.post(f"{BASE}/lists/2/leave/", headers=HEADERS, params=USER)

# Toggle bought
requests.post(f"{BASE}/items/5/toggle/", headers=HEADERS, params=USER)