Import from CSV or Excel
The import route with no AI and no credits: upload a spreadsheet, map the columns, and AreaCacao creates or updates your recipes in bulk.
What it is
Import from CSV or Excel turns a spreadsheet into AreaCacao recipes. You prepare the file, you decide what each column means, and the importer creates (or updates) the recipes. No AI reads the file, and no credits are used.
- Path:
https://app.areacacao.com/import-recipe, Upload new tab. - How to get there: sidebar → FORMULATION → Import recipes → Upload new tab. The card sits below the photo/PDF drop zone.
- Availability: on by default on every plan. The only exception is the older free accounts (created before sign-up required choosing a plan): clicking Import CSV/Excel shows the notice "Excel or CSV import is included in the Starter and Pro plans." with the See plans button.
How it differs from importing a photo or a PDF
| CSV / Excel | Photo or PDF | |
|---|---|---|
| How the file is read | Deterministic: your columns, your mapping | AI interprets the image |
| Credits | 0 | ~15 per image, ~25 per PDF |
| Usage limit | No usage limit (there is a technical rate limit, see below) | Bounded by your credit balance |
| Several recipes per file | Yes, as many as fit in the sheet | One per file; if the file contains several, you choose which one to import |
| Who decides what each value means | You, in the mapping step | The AI, and you correct it afterwards |
The only place AI can get involved is optional and your choice: auto-completing ingredients that aren't in your catalog (see Ingredients that don't match the catalog).
The card and its two buttons
The card is titled "CSV or Excel (no credits)" and reads: "Import your recipes from a spreadsheet. No credits used and no usage limit. Import one or many recipes at once."
It has two buttons and one expandable block:
- Import CSV/Excel — opens the wizard.
- Download template — generates the file right in your browser, without going through the server.
- Quick guide: how to prepare your file — an expandable block with the fill-in rules, the list of valid
filling_typevalues and therecipe_typevalues.
If the card isn't on your screen, the feature has been switched off from infrastructure (the RECIPE_IMPORT_CSV_ENABLED flag). It is on by default: it only goes off when the flag is explicitly set to false.
The template
Download template saves areacacao-recipe-template.csv to your machine. It is a CSV with a UTF-8 BOM (so Excel keeps accented characters) containing the canonical header row plus three example recipes, picked to teach the three patterns the importer understands:
- Passion fruit ganache — a simple filling: five rows share the same
recipe_name, and the last one carries the steps. Four ingredients are linked byingredient_codeand one (the passion fruit purée) by name only. - Classic cocoa truffle — a filling with layers: the
partcolumn separates "Center" from "Coating". - 70% dark bar — a chocolate recipe: it uses
chocolate_typeandcocoa_percentand leavesfilling_typeempty.
The template follows the interface language: with the app in English, the file is named areacacao-recipe-template.csv and the recipe, ingredient, section and step names are in English; the headers and the identifiers (ganache_bombon, negro…) are always the same. The example costs are per kilo (cost_unit = kg) and in US dollars (USD).
You are not required to use the template: you can import your own sheet with your own headers and tell the wizard what each column is.
Columns
The template ships with 17 columns, in this order:
recipe_name, recipe_type, chocolate_type, filling_type, cocoa_percent, part, ingredient_code, ingredient_name, quantity, unit, weight_g, cost_per_unit, cost_unit, cost_currency, is_supply, supply_code, steps
The wizard can map 18 fields: the 17 above plus recipe_id (Recipe ID), which exists as a mapping target even though the template doesn't include it.
| Field | Label in the wizard | What it does |
|---|---|---|
recipe_name | Recipe name | The only required field. It groups rows: several rows with the same name make up a single recipe. |
recipe_id | Recipe ID | Updates an existing recipe instead of creating a new one. |
recipe_type | Recipe type | Accepted values: chocolate, filling, relleno. Anything else (or empty) is treated as generic. |
chocolate_type | Chocolate type | Chocolate recipes only. |
filling_type | Filling type | The filling's technical type; it enables range-based validation. |
cocoa_percent | Cocoa % | The recipe's cocoa percentage. |
part | Part / section | Separates layers or sections within the same recipe. |
ingredient_code | Ingredient code | Links the row to an exact ingredient sheet in your catalog. |
ingredient_name | Ingredient name | Used to look the ingredient up by name when there's no code. |
quantity | Quantity | The ingredient's quantity. |
unit | Unit | The unit the quantity is expressed in. |
weight_g | Weight (g) | Weight in grams. If left empty, the importer tries to convert it from quantity + unit. |
cost_per_unit | Cost per unit | The line's unit cost. |
cost_unit | Cost unit | The unit the cost refers to (for example, kg). If you map the cost but not this column, the cost is read in each row's unit (a row in g is taken as cost per gram) and the preview warns you about it. |
cost_currency | Currency | The cost's currency. |
is_supply | Is supply | Marks the row as a supply (non-edible material). |
supply_code | Supply code | Links the row to a supply in your catalog, by code. |
steps | Steps / preparation | Every step in one single cell, separated by the vertical-bar character. |
How rows are grouped
Rows are grouped by normalized recipe_name: lowercased, accents stripped, internal whitespace collapsed. So "Ganache de Maracuyá" and "ganache de maracuya" end up in the same recipe.
Fill-in rules the importer enforces
- One ingredient per row. Don't put the whole ingredient list in a single cell — the importer can't split it.
- Steps separated by
|. Filling instepson any one row of the recipe is enough. - Layers via
part. Samerecipe_nameon every row, layer name inpart. If the recipe has a single layer, leavepartempty. filling_typemust be the exact identifier, lowercase with underscores. Plainganacheis not valid; the classic bonbon ganache isganache_bombon. The full list lives in the Quick guide block on the screen itself.
The wizard, step by step
The wizard is titled "Import recipes from CSV" and has five screens.
Upload. Drag the file onto the "Drag your file here" zone or click to browse. It accepts .csv and .xlsx, and one file per import (the picker does not allow multiple selection).
Map. A table with three columns — File column, Example and AreaCacao field — where you pick a destination for each header. It arrives pre-filled by the wizard's own detection, which recognizes Spanish, English, French and Portuguese synonyms regardless of case or accents (Nombre de la receta, recipe name, recette, receita… all resolve to recipe_name).
Columns you don't need stay on Skip. The same AreaCacao field cannot be assigned to two columns: picking it on one clears it from the other.
If you haven't mapped the recipe name, the wizard won't let you continue and shows: "Tell us at least which column holds the recipe name to continue."
Options. You choose what happens to ingredients we can't find. See the next section.
Preview. The server works out what would happen without writing anything: "Here's what we'll do. Nothing has been saved yet." You get counts for Recipes to create, Recipes to update, Recipes total, Ingredients linked, Ingredients to create, Ingredients pending and Supplies not found, plus an Issues found list keyed by row number. If you mapped the cost per unit without the cost_unit column, a notice explains how that cost will be read.
Import. You press Import and the job moves to the background. The screen polls its status every 2.5 seconds and, while it works, shows "Importing your recipes…" with the Close (keeps running in the background) button. When it finishes it shows "Import complete" with the summary "N created · N updated · N with errors.", a My recipes button and, if a single recipe was created, View recipe, which opens it in the editor with the validation panel.
Ingredients that don't match the catalog
The importer resolves each row like this: if there's an ingredient_code, it looks up that exact ingredient sheet; otherwise it searches your catalog by name. If the name matches several ingredient sheets, the line is left pending with a short list of candidates for you to pick from in the recipe; if the ingredient sheet was inferred by stripping a brand or a percentage from the name, the line is flagged for you to check. When nothing matches, it applies the choice you made in the Options step:
- Create missing ingredients as pending (no cost) — "Ingredients we can't find are added marked as pending, with no nutrition or cost data. You can complete them later. Uses no credits." This is the default.
- Auto-complete missing ingredients with AI — 5 credits per ingredient — "For each ingredient we can't find, AI estimates macros, allergens and cost data. Charged 5 credits per new ingredient."
The AI mode is the only way this route can consume credits, and the charge is per new ingredient — not per recipe and not per file. The pending mode never touches your credits.
Supplies
Rows flagged with is_supply or carrying a supply_code are treated as supplies. They are linked by code only against your supplies catalog. If the code doesn't exist, the line is still imported but flagged for review, and the Supplies not found count in the preview warns you beforehand. The importer never creates new supplies — not even in AI mode, which only applies to ingredients.
Create versus update
- No
recipe_id→ a new recipe is always created. - With
recipe_id→ if that id exists and is yours, the recipe is updated. If it doesn't exist or isn't yours, a new recipe is created instead. - When a recipe is created and its name already exists in your catalog, AreaCacao differentiates the name automatically rather than blindly duplicating it. This applies on create only, never on update.
- One failing recipe does not abort the batch: it is flagged with its error and the importer moves on to the next one.
Limits
| Limit | Value |
|---|---|
| Formats | .csv and .xlsx |
| Files per import | 1 |
| Maximum file size | 20 MB |
| Maximum data rows | 20,000 (header excluded) |
Sheets read from an .xlsx | The first one only |
| Concurrent imports | 1 per user |
| Rate limit | 20 upload/parse operations per 10 minutes, per user |
If you try to start an import while another one is queued or processing, the server rejects it: you have to wait for the previous one to finish.
What it does NOT do
- It does not read your file with AI. The column mapping is yours and the parsing is deterministic.
- It does not appear in the History tab. That tab lists photo and PDF imports. Even though the wizard says "You can close this window; the import keeps running and you'll see it in History.", spreadsheet imports are not currently listed on any screen: their status is only visible in the wizard window while you keep it open. If you close it, the import carries on, but you'll have to check My recipes to see the result.
- It cannot be canceled. Once you press Import there is no cancel button; the wizard only lets you close the window.
- It does not create new supplies.
- It does not read more than one sheet from an Excel workbook.
- It does not import from a Google Sheets link or any URL: the file has to be uploaded. Importing from a web page is a separate route — see Import a recipe from a URL.
- It does not validate
filling_typefor you. If you write an identifier that doesn't exist, the recipe is imported without filling-specific technical validation.
Next steps
Import a photo or PDF
Upload one or more images or PDFs of recipes and let AI turn them into recipes in your recipe book, step by step.
Import a recipe from a URL
Not available yet: how URL import (pasting the link to a published recipe and getting it back as an editable draft) will work once it's switched on.