Browse documentation

🧭 Start Here

Blackcap Overview ✨ Blackcap Feature Catalog Installation First Run

🚀 Deploy Blackcap

Platform Stacks and Raspberry Pi Hardware Raspberry Pi Deployment Raspberry Pi Client Services GCP Deployment Application Updates Environment Variables and Secrets Reverse Proxy and TLS Background Jobs and Schedules

🛠️ Administer Blackcap

Organizations Users, Permissions, and Authentication Configuration Workspace Backups and Restore Database Administration Regression Testing Performance and Job Status Audit, Access Activity, and Logging GeoIP and Access Location Data Retention and Purge Support Requests API Tester and Postman Instance Reporting

🍽️ Use Recipes

Recipes and the Recipe Library Recipe Import and Discovery Recipe Editing and Cache Artifacts Recipe Sharing Social Recipe Import AI Recipe Image Generation

📅 Plan Meals

Meal Planner

🛒 Use Shopping Lists

Shopping Lists and Shop a List External and Household Shopping 🧩 Chrome Extension Shop With

🧺 Manage Kitchen Inventory

🧺 Kitchen Inventory

🖥️ Use Displays

Displays and Connections Assigning and Scheduling Display Content Remote Pi Client E-Ink Rendering Menu Refresh and Rendering Noun Project Footer Images

🧑‍🍳 Cook with Let’s Cook

🧑‍🍳 Let’s Cook 🧑‍🍳 Let’s Cook Controls and Timers

🤖 Use and Administer AI

🤖 AI in Blackcap 🤖 AI Providers and Connections 🤖 AI Seeds and Usage

🧩 Use the Chrome Extension

🧩 Blackcap Chrome Extension 🧩 Chrome Extension Recipe Capture 🧩 Chrome Extension Shop With 🧩 Chrome Extension Release and Privacy

🎮 Play Games

🎮 Games and Trivia

🔌 Integrations

Email Integration Cloud Storage Integrations Voice Assistants Shop With Integrations Authentication Providers

⚙️ Develop Blackcap

Application Architecture Database Service and Data Access SQLite and PostgreSQL Database Migrations Background Job Architecture Testing API Architecture Security and Organization Scoping UI, Icons, and Documentation Assets Blackcap-Safe Emoji Documentation Standards Terminology

⚠️ Troubleshoot Blackcap

⚠️ Troubleshooting Deployment Troubleshooting Display Troubleshooting Recipe Import Troubleshooting 🤖 AI Troubleshooting Backup Troubleshooting Database Troubleshooting Diagnostic Organization Clones Support Requests

Recipe Import and Discovery

Audience: User, Org Admin, Developer, Support Related: Overview · Editing And Cache · Social Import · Recipe Import

Normal recipe import accepts supported URLs and extracts structured data using deterministic sources first, including JSON-LD and page content, with rendering or slower-site handling when required. Recipe Discovery searches configured providers and returns candidate pages for capture.

Imported recipes should preserve source attribution, identify incomplete content, and move through review or editing rather than silently inventing missing ingredients or instructions.

Mobile URL, QR, and photo capture

Admin and Mobile can feed several capture inputs into the normal recipe pipeline:

  • paste a recipe URL directly;
  • photograph or upload a printed recipe page that contains a footer URL;
  • scan a QR code that resolves to a recipe URL;
  • upload one or more recipe photos/screenshots for image-based capture.

URL scanning uses a bounded sequence: pyzbar/libzbar as the fast QR path, OpenCV QR detection as a fallback, then OCR for printed URLs when the image is not QR-based. Raspberry Pi and GCP deployment scripts install libzbar0, and both dependency files include pyzbar.

Mobile uploads are resized and compressed before upload to reduce failures when a phone sleeps or has a slow connection. The full image is preserved rather than cropped by default. Multiple capture images can be combined into one recipe. Image-captured recipes remain organization-scoped and flow through the shared recipe, editable-content, indexing, and cache services.

Image capture is different from refreshing a public recipe source. Do not claim that an image-only recipe can be refreshed from a website unless it also has a valid source URL and the current workflow explicitly supports that action.

Recipe Discovery workflow

Recipe Discovery is a web-recipe import workflow for both the Admin UI and Mobile UI. It lets a user search for recipes, review Blackcap-styled result cards, preview extracted recipe content, edit the preview, choose a layout, and save the result into the current organization’s Recipe Library.

Recipe Discovery intentionally does not embed arbitrary recipe websites. Many recipe sites block iframes, mobile iframe UX is poor, and Blackcap’s import preview is the safer workflow.

Current workflow

  1. Open Recipe Discovery from Admin, Mobile, or a Meal Planner slot.
  2. Enter search text and optionally choose a recipe type.
  3. Add “ingredients on hand” as chips using inventory, typeahead, or freeform text.
  4. Search results are powered by Google CSE but rendered as native Blackcap result cards.
  5. Select Preview on a specific recipe result.
  6. Blackcap asynchronously extracts recipe metadata, ingredients, instructions, thumbnail, source URL, header info, and automatic cleanup estimate metadata.
  7. Edit the preview if needed.
  8. Choose or confirm the recipe type and layout in Preview/Edit.
  9. Save the recipe.
  10. Blackcap saves the recipe, indexes ingredients/search content, and queues the normal async cache build. The cache build can refresh total-time, nutrition, and cleanup-rating metadata shown on recipe cards.

Manual URL preview remains available even when search is disabled or Google is unavailable.

Meal Planner return context

Recipe Discovery can be launched from a Meal Planner slot in either Admin or Mobile. When the URL includes meal_plan_date, meal_slot_id, and return_to, the save flow keeps the normal Recipe Discovery behavior and then creates a Meal Planner entry for the selected date/slot.

Admin example:

/admin/recipe-discovery?meal_plan_date=2026-05-28&meal_slot_id=<slot_id>&return_to=meal_planner

Mobile example:

/mobile/recipe-discovery?meal_plan_date=2026-05-28&meal_slot_id=<slot_id>&return_to=mobile_meal_planner

Save behavior with Meal Planner context:

  1. Save the recipe into the current organization as usual.
  2. Write editable content, ingredients, and search index data as usual.
  3. Queue the normal recipe cache/PDF/image build.
  4. Create a recipe-backed Meal Planner entry for the supplied date and slot.
  5. Return the user to the appropriate Meal Planner page with the selected date still in context.

The context is optional. Standalone Recipe Discovery continues to save only to the Recipe Library.

Search provider recommendation

The implemented provider foundation supports:

  • manual_only — safe fallback. Users paste a recipe URL and use the same preview/edit/save workflow.
  • google_embedded_cse — Google CSE / Search Element mode. This uses the browser Search Element with only the Google Search Engine ID / cx; no API key or API secret is required.

The backend does not scrape Google search-result HTML. Google renders search results in the browser, and Blackcap reads the rendered result metadata to build its own native result cards. The backend only receives the selected recipe URL for preview/extraction.

The UI keeps the Google source hidden when native result cards load successfully. It opens the Google source/verification area only when robot verification is detected or results fail to load. The source area can be closed after verification.

Older google_hosted_cse, google_programmable_search, google_cse, and google_hosted setting values are normalized to google_embedded_cse for compatibility.

Platform settings

Recipe Discovery settings live under Configuration → Platform → Recipe Discovery.

Setting key Scope Purpose
recipe_discovery.search_provider_enabled Platform Enables Recipe Discovery search. Manual URL fallback remains available when disabled.
recipe_discovery.search_provider_type Platform manual_only or google_embedded_cse.
recipe_discovery.google_cse_id Platform Google Search Engine ID / cx. Required for google_embedded_cse.
recipe_discovery.search_result_limit Platform Provider result count, capped to a safe range.
recipe_discovery.extraction_timeout_seconds Platform Reserved extraction timeout setting for provider/extractor tuning.
recipe_discovery.positive_terms Platform Newline-separated search terms appended to queries.
recipe_discovery.excluded_phrases Platform Newline-separated phrases converted to negative quoted search terms.
recipe_discovery.excluded_title_terms Platform Newline-separated terms converted to negative intitle: filters.

Use Restore Search Defaults on that configuration page to restore the built-in query tuning defaults without changing provider settings, the Google CSE ID, result limit, or extraction timeout.

Organization-scoped layout defaults continue to come from recipe.default_layout.

Query tuning

Recipe Discovery builds the provider query from:

  • search text
  • selected recipe type, unless “Any”
  • ingredient chips
  • configured positive terms
  • configured excluded phrases
  • configured excluded title terms

The defaults bias searches toward specific recipe detail pages by adding terms such as recipe, ingredients, and instructions, and filtering common roundup/list/menu pages such as recipe roundup, recipe collection, dinner ideas, menus, and title terms like recipes, roundup, collection, ideas, and dinners.

Ingredient chips

The Ingredients on hand control is shared by Admin and Mobile.

It supports three ways to add chips:

  1. Kitchen Inventory picker — small icon button next to the label opens a compact popup of on-hand inventory matches. Selecting an item adds a chip and closes the popup.
  2. Ingredient typeahead — suggestions come from the existing org-scoped ingredient index.
  3. Freeform entry — if the ingredient is not in Kitchen Inventory or existing recipes, users can still keep it as a search chip.

Users can add chips with Enter, Tab, or comma. Chips can be removed with the chip’s remove button.

Kitchen Inventory suggestions are optional and require the user to have inventory view permission. The endpoint uses the inventory service layer; no direct SQL is added.

Admin workflow

The Admin UI adds Recipe Discovery to the Everyday navigation. The larger-screen layout uses a viewport-aware three-panel workspace:

  1. Search Criteria — search text, recipe type, ingredient chips, inventory picker, and manual URL fallback.
  2. Search Results — native Blackcap cards rendered from Google CSE results, with compact page controls.
  3. Preview/Edit — editable extracted recipe data, recipe type, layout, save/start/return actions, and progress feedback.

Panel behavior:

  • Preview/Edit starts collapsed.
  • Searching collapses Search Criteria and expands Search Results.
  • Selecting a result collapses Search Results and expands Preview/Edit.
  • Search Results and Preview/Edit have independent panel scrolling.
  • The page header can scroll away to maximize usable workspace.

Mobile workflow

The Mobile UI adds Recipe Discovery to the mobile Views menu. It uses a step-based flow:

  1. Search Criteria / Manual URL
  2. Search Results
  3. Preview / Edit / Save

Mobile behavior:

  • Layout is chosen in Preview/Edit, not in the Search step.
  • Recipe type and layout are shown side-by-side in Preview/Edit where space allows.
  • Save and Start Over sit together in the Preview/Edit action area.
  • Save success/failure messages appear below the action buttons.
  • Save is disabled after a successful save until the user changes preview content again.
  • Search result pagination supports page chips, previous/next, and horizontal swipe.
  • Page chips adapt to the available width and keep the current page visible.

Layout behavior

Recipe Discovery exposes friendly layout labels:

  • Full Widthsingle_page
  • Split Columnstwo_page

The selector defaults to the current organization’s default recipe layout. Changing the selector affects only the recipe being saved from the current preview.

Endpoints

Method Path Purpose
GET /admin/recipe-discovery Admin Recipe Discovery page.
GET /mobile/recipe-discovery Mobile Recipe Discovery page.
POST /recipes/discovery/search Provider-backed recipe search.
GET /recipes/discovery/inventory-ingredients Optional org-scoped Kitchen Inventory ingredient suggestions.
POST /recipes/discovery/preview Queue async preview/extraction for a selected result.
POST /recipes/discovery/preview-url Queue async preview/extraction for a manually pasted URL.
GET /recipes/discovery/preview-status/<job_id> Poll preview job status/result.
POST /recipes/discovery/save Save edited preview into the Recipe Library and queue cache build.

All endpoints require recipes.create. Kitchen Inventory suggestions additionally require inventory.view; if missing, the page remains usable without inventory suggestions. Optional Meal Planner context parameters are validated against the current organization before a meal-plan entry is created.

Cleanup metadata

Recipe Discovery participates in the same cleanup-rating pipeline as URL import and cache rebuild. Preview/save can generate an automatic 🛁 cleanup estimate from the extracted recipe body, and the queued cache build can refresh that estimate after editable content is materialized. See Recipe Cleanup Rating for thresholds, display behavior, Made It feedback, and cache rebuild behavior.

Data model

No new permanent Recipe Discovery table is required for the current implementation.

Preview extraction uses the existing durable background_jobs table through background_job_service with job type recipe_discovery_preview. The extraction result is stored in the job result JSON. Saved recipes continue through the centralized recipe services, editable recipe content, ingredient/search indexing, and cache queue.

A future hosted deployment could add a temporary preview draft table if previews need longer-lived collaboration, multi-user resume, or cleanup reporting.

Security and SSRF protections

Recipe Discovery URL preview validates URLs before fetch:

  • only http and https schemes are allowed
  • missing host names are rejected
  • DNS is resolved before fetch
  • localhost, private, link-local, multicast, reserved, and unspecified IP targets are blocked by default
  • extracted content is edited as text fields, not executed as page HTML
  • Google API keys are not used or exposed
  • only the non-secret Google Search Engine ID is exposed to JavaScript

One deferred hardening item is redirect-chain revalidation. The current shared parser fetch may follow redirects after initial validation. For hosted/SaaS deployment, the shared fetch helper should validate the final redirect target before downloading content.

Cache behavior

Save creates or updates the recipe through the existing recipe service path, writes editable content, rebuilds ingredient/search indexes, and queues the standard recipe cache build asynchronously.

The save endpoint does not synchronously build PDF/PNG assets.

Files added

  • inky_admin/blueprints/recipe_discovery.py
  • inky_admin/services/recipe_discovery_service.py
  • inky_admin/services/recipe_search_provider_service.py
  • inky_admin/services/web_recipe_extraction_service.py
  • inky_admin/services/recipe_discovery_search_defaults.py
  • inky_admin/templates/recipe_discovery.html
  • inky_admin/templates/mobile_recipe_discovery.html
  • inky_admin/static/css/recipe_discovery.css
  • inky_admin/static/js/recipe_discovery.js
  • importing-and-discovery.md
  • database/migrations/043_recipe_discovery_embedded_cse.sql
  • database/migrations/044_recipe_discovery_search_tuning.sql

Files updated

  • inky_admin/blueprints/__init__.py
  • inky_admin/services/config_setting_map.py
  • inky_admin/services/config_ui_service.py
  • inky_admin/services/security_service.py
  • inky_admin/services/background_job_service.py
  • inky_admin/templates/base_admin.html
  • inky_admin/templates/config_index.html
  • inky_admin/templates/config_scoped_settings.html
  • inky_admin/templates/includes/mobile_header.html
  • inky_menu_config.ini.example

Restart

sudo systemctl restart inky_admin.service

Testing checklist

  • Search text returns provider results when provider is configured.
  • Recipe type is included in the constructed provider query when not “Any”.
  • Ingredient chips are included in the constructed provider query.
  • Inventory picker adds chips and closes.
  • Existing ingredient typeahead adds chips.
  • Freeform ingredients can be added with Enter, Tab, or comma.
  • Provider disabled/not configured shows a clear message and keeps manual URL available.
  • No results state is clear.

Search results

  • Native Blackcap result cards render from Google CSE results.
  • Search Results panel scrolls independently.
  • Result cards show title, source/domain, snippet, thumbnail when available, Preview, and Open Source.
  • Preview queues extraction for the selected recipe URL.
  • Page controls work on Admin.
  • Page controls and swipe work on Mobile.
  • Google source opens for verification/fallback and can be closed after verification.

Layout

  • Layout defaults from organization recipe configuration.
  • Layout is selected in Preview/Edit.
  • Saved recipe uses selected layout.

Preview / extraction

  • Preview job is created and appears as queued/running/completed.
  • Metadata/header info, ingredients, instructions, image URL, and source URL populate when extraction succeeds.
  • Partial extraction remains editable.
  • Failed extraction produces editable fallback fields.
  • Invalid/private URLs are blocked.

Save

  • Save creates recipe in current organization.
  • Edited title/content are saved.
  • Recipe type and layout are saved.
  • Editable ingredients and instructions are saved.
  • Ingredient/search indexes update.
  • Cache build is queued asynchronously.
  • Recipe appears in Recipe Library after save.
  • Saved recipe is not marked edited unless the discovered content was actually changed before save.

Meal Planner context

  • Admin Meal Planner launches Recipe Discovery with date/slot context.
  • Mobile Meal Planner launches Recipe Discovery with date/slot context.
  • Save creates the recipe and queues cache normally.
  • Save also creates the Meal Planner entry when context is present.
  • Return context goes back to Admin or Mobile Meal Planner as appropriate.
  • Standalone Recipe Discovery still saves without creating a Meal Planner entry.

Mobile

  • Search → Results → Preview/Edit → Save flow works.
  • Browser back returns preview to results and results to search criteria where practical.
  • Start Over returns to a blank search screen.
  • Save success/failure message appears below Preview/Edit buttons.
  • Save stays disabled after a successful save until content changes.
  • Touch targets are usable.

Admin

  • Recipe Discovery appears in Admin navigation.
  • Three-panel workflow works on desktop.
  • Search refinement works.
  • Preview/edit/save works without full page reload.
  • Header panels scroll away and inner panels scroll independently.

Security / scope

  • Users without recipes.create are blocked.
  • Recipes save only into the current organization.
  • Ingredient suggestions come from org-scoped index results.
  • Kitchen Inventory suggestions respect inventory permissions and organization scope.
  • No direct SQL calls are introduced for Recipe Discovery.
  • No Recipe Discovery API key is stored or logged.

Regression

  • Existing Add Recipe still works.
  • Chrome Extension recipe push still works.
  • Recipe cache queue still works.
  • Recipe Library still works.
  • Shopping lists and Shop a List are unaffected.

Slow-site capture and recipe metadata

Platform slow recipe websites

System Admins can manage the platform-scoped Slow Recipe Websites configuration from Platform Configuration. The slow-site threshold defaults to 50 seconds and is stored as the platform setting slow_recipe_sites.threshold_seconds.

When a recipe cache build for a source URL exceeds the threshold, Blackcap records the normalized source domain in slow_recipe_source_sites. The list is persistent and survives normal performance-metric purges. Auto detection updates sample count, average duration, maximum duration, last duration, detection timestamps, and the last full recipe URL that triggered the slow-site detection. Manual entries can be added from a domain or full URL; a full URL is also stored as the retry test URL. Removal is soft-delete style by setting the status to removed; a future slow cache build can reactivate the domain.

Domain normalization lowercases the host, strips the port and a leading www., and ignores path/query/fragment for the domain key. The full recipe URL is stored separately for retry testing when available. Other subdomains are preserved so recipes.example.com remains distinct from example.com.

Slow-site retry testing

The Slow Recipe Websites configuration page includes a Retry action when Blackcap has a stored full recipe URL for the domain. Retry now starts a tracked background job and returns immediately so the Platform Configuration page does not sit waiting on a recipe import/cache build. The slow-site row is marked queued / running while the job is active and is updated when the retry finishes.

The background retry runs a test cache build against the stored full URL. If the current organization already has an active recipe for the same full URL and the recipe has not been manually edited, Blackcap uses that recipe for the test. Otherwise, it creates a temporary web-backed recipe for the stored URL, runs the cache build, and archives the temporary recipe after the test completes.

If the retry cache build succeeds and completes below the configured slow-site threshold, Blackcap marks the slow-site row removed, which re-enables URL-only Quick Add for that domain. If the build fails or still meets/exceeds the threshold, the domain stays active and remains blocked for URL-only Quick Add. Retry outcomes are stored on the slow-site row with the last retry time, duration, status, message, recipe id, and whether an existing recipe was used. The retry background job is visible in Background Operations under Recipe Cache work. No separate purge is required for retry metadata; it is part of the persistent slow-site row. Temporary retry recipes are archived immediately after the retry and then follow the normal recipe/archive retention behavior.

Slow-site capture behavior

URL-only quick add is blocked for active slow-site domains in the Chrome Extension, Admin URL add, and Mobile URL add flows. The user is guided to use full page capture so Blackcap can use recipe details already present in the browser. Full active-page capture is not blocked.

Recipe Discovery is not blocked. It receives a warning that the site is expected to take longer, then continues normally.

Meal Planner people served

Meal Planner settings now include Default people served, organization-scoped and defaulting to 3. Meal slots can override people served for a specific day/slot, and the toolbar bulk editor can apply a people count across a date range and selected meal slots.

When a recipe is added to a meal slot, Blackcap calculates the multiplier from:

people_to_serve / recipe_servings

The calculated multiplier is stored on the meal plan entry with source calculated_from_people so display rendering, Let’s Cook, and shopping-list generation use the same value. Manual multiplier edits switch the entry back to source manual; bulk people updates recalculate calculated entries by default and only overwrite manual entries when explicitly requested.

Servings parsing supports numeric values, text like Serves 4, and ranges. Ranges use the midpoint as a practical first pass. Non-serving yields such as 1 loaf or 1 pie are treated as unknown servings and fall back to 1x.

Whole-batch scaling

Whole-batch recipes use integer multipliers:

max(1, ceil(people_to_serve / recipe_servings))

The first-pass heuristic detects titles/yields containing words such as cake, pie, bread, loaf, rolls, muffins, cookies, bars, tart, cheesecake, brownie, or batch. Recipe metadata can later carry an override using the label Whole-batch scaling.

Recipe difficulty

Difficulty is derived from cleanup score, active time, and ingredient count when at least two inputs are available. The labels are:

  • 🟢 Easy
  • 🟡 Moderate
  • 🟠 Involved
  • 🔴 Ambitious

Scoring components are 0–3 points each:

  • Cleanup: low score to high score
  • Active time: <=15, 16–30, 31–60, >60 minutes
  • Ingredient count: <=6, 7–12, 13–20, >20

Totals map to Easy 0–2, Moderate 3–4, Involved 5–6, and Ambitious 7–9.

Time and effort search filters

Recipe search surfaces a compact Time & Effort filter instead of adding separate cluttered facets. Current options include quick meals, easy recipes, moderate-or-easier, involved/ambitious, under 30 minutes, and under 60 minutes. Difficulty pills appear alongside existing recipe metadata pills where space allows.

On this page