API reference

Food

Recipes, collections, the meal plan, shopping lists, the pantry, suggestions and importing.
GET/v1/hooks/food/r/:token

A recipe by its public link (no sign-in): the recipe without its owner's notes or rating. 404 once the link is off.

Auth
None.

Path parameters

  • token

    A secret from a link: an issue automation rule's incoming-webhook token (shown once when issued), a map's share link, a notification recipient's confirm and unsubscribe link, a Drive public link (/l/<token>), a Vehicles drive's share link, or a Mirage interaction's token (itk_…, sent with the interaction, good for 15 minutes), or the token in the link to a file of a message Mirage sent to Discord, or a Marketing link's sealed token (a tracked click, the open pixel, unsubscribe and the preference centre, a double opt-in confirmation); or a Food recipe's public link (/r/<token>) or a household's calendar feed.

curl 'https://api.cactive.com.au/v1/hooks/food/r/{token}'
Send it from this page with your session or a key.

Response 200

{
  recipe: {
    version: number
    createdAt: number
    updatedAt: number
    title: string
    description?: string
    source?: {
      kind: "text" | "photo" | "web" | "manual" | "melt" | "paprika" | "mela" | "crouton" | "copymethat" | "assistant" | "copy"
      url?: string
      name?: string
      author?: string
    }
    tags: string[]
    ownerId: string
    steps: {
      id: string
      section?: string
      text: string
      timers?: {
        seconds: number
        label?: string
      }[]
    }[]
    favourite?: boolean
    recipeId: string
    servings: number
    yieldLabel?: string
    prepMinutes?: number
    cookMinutes?: number
    totalMinutes?: number
    ingredients: {
      id: string
      section?: string
      quantity?: number
      quantityMax?: number
      unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
      item: string
      note?: string
      ingredientId?: string
      optional?: boolean
    }[]
    cuisines: string[]
    courses: string[]
    claimedDiets: string[]
    difficulty?: "medium" | "easy" | "hard"
    spoons: "au" | "us"
    notes?: string
    rating?: number
    household: boolean
    cookedCount: number
    lastCookedAt?: number
    images: {
      imageId: string
      versionId?: string
      mime?: string
      width?: number
      height?: number
      alt?: string
      url: string
      thumbUrl: string
    }[]
    nutrition: {
      perServing: {
        kj: number
        kcal: number
        protein: number
        fat: number
        saturatedFat: number
        carbs: number
        sugars: number
        fibre: number
        sodium: number
      }
      total: {
        kj: number
        kcal: number
        protein: number
        fat: number
        saturatedFat: number
        carbs: number
        sugars: number
        fibre: number
        sodium: number
      }
      coverage: number
      unmatched: string[]
    }
    allergens: string[]
    diets: string[]
    access: "owner" | "household" | "public"
    ownerName?: string
    publicUrl?: string
    cost?: {
      total: number
      perServing: number
      coverage: number
      priced: number
      measured: number
    }
  }
}
GET/v1/hooks/food/plan/:token

A household's meal plan as an iCalendar feed (<token>.ics, no sign-in): two weeks back to eight ahead, at meal times.

Auth
None.

Path parameters

  • token

    A secret from a link: an issue automation rule's incoming-webhook token (shown once when issued), a map's share link, a notification recipient's confirm and unsubscribe link, a Drive public link (/l/<token>), a Vehicles drive's share link, or a Mirage interaction's token (itk_…, sent with the interaction, good for 15 minutes), or the token in the link to a file of a message Mirage sent to Discord, or a Marketing link's sealed token (a tracked click, the open pixel, unsubscribe and the preference centre, a double opt-in confirmation); or a Food recipe's public link (/r/<token>) or a household's calendar feed.

curl 'https://api.cactive.com.au/v1/hooks/food/plan/{token}'
Send it from this page with your session or a key.

Response 200 with no body

GET/v1/me/food/settings

Your Food settings (measures, spoons, servings, diets, allergens, suggestions, Health logging, week start) and your household.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:read (when actor.type === "user")
Get an API key

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:read on a key made by a person.
curl 'https://api.cactive.com.au/v1/me/food/settings' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  settings: {
    measure: "metric" | "original" | "imperial"
    spoons: "au" | "us"
    defaultServings: number
    diets: string[]
    avoidAllergens: string[]
    weeknightMinutes?: number
    weatherSuggestions: boolean
    healthLogging: boolean
    calendar?: {
      orgId: string
      calendarId: string
    }
    weekStartsOn: number
    receiptMail?: {
      orgId: string
      mailboxId: string
      address: string
      since: number
      backfilledAt?: number
    }
    useSoonAlerts: boolean
    voiceControl: boolean
    weeklyBudget?: number
    timeZone?: string
  }
  home: {
    homeId: string
    name: string
    members: {
      userId: string
      name?: string
      role: "owner" | "member"
      joinedAt: number
    }[]
    createdAt: number
    receipts?: {
      token?: string
      autoAdd?: boolean
      confirmation?: {
        code?: string
        link?: string
        at: number
      }
    }
  }
}
PATCH/v1/me/food/settings

Changes the person's Food settings (only the fields given; null clears one).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Request body

  • measure"original" | "metric" | "imperial"
  • spoons"au" | "us"
  • defaultServingsinteger

    1–50.

  • diets[]

    Up to 10 items.

  • avoidAllergens[]

    Up to 20 items.

  • weeknightMinutesintegeror null

    10–240.

  • weatherSuggestionsboolean
  • healthLoggingboolean
  • weekStartsOninteger

    0–6.

  • useSoonAlertsboolean
  • voiceControlboolean
  • weeklyBudgetnumberor null

    1–100000.

  • timeZonestring

    Up to 60 characters. Matches ^[A-Za-z_]+(\/[A-Za-z0-9_+-]+){0,2}$.

Also checked: Unknown fields are rejected.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X PATCH 'https://api.cactive.com.au/v1/me/food/settings' \
  -H "Authorization: Bearer $CACTIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "measure": "original",
    "spoons": "au",
    "defaultServings": 1
  }'
Send it from this page with your session or a key.

Response 200

{
  settings: {
    measure: "metric" | "original" | "imperial"
    spoons: "au" | "us"
    defaultServings: number
    diets: string[]
    avoidAllergens: string[]
    weeknightMinutes?: number
    weatherSuggestions: boolean
    healthLogging: boolean
    calendar?: {
      orgId: string
      calendarId: string
    }
    weekStartsOn: number
    receiptMail?: {
      orgId: string
      mailboxId: string
      address: string
      since: number
      backfilledAt?: number
    }
    useSoonAlerts: boolean
    voiceControl: boolean
    weeklyBudget?: number
    timeZone?: string
  }
}
GET/v1/me/food/home

Your household: its name and members (made, yours alone, the first time).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:read (when actor.type === "user")
Get an API key

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:read on a key made by a person.
curl 'https://api.cactive.com.au/v1/me/food/home' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  home: {
    homeId: string
    name: string
    members: {
      userId: string
      name?: string
      role: "owner" | "member"
      joinedAt: number
    }[]
    createdAt: number
    receipts?: {
      token?: string
      autoAdd?: boolean
      confirmation?: {
        code?: string
        link?: string
        at: number
      }
    }
  }
}
PATCH/v1/me/food/home

Renames your household.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Request body

  • namestringrequired

    1–60 characters.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X PATCH 'https://api.cactive.com.au/v1/me/food/home' \
  -H "Authorization: Bearer $CACTIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Example"
  }'
Send it from this page with your session or a key.

Response 200

{
  home: {
    name: string
    homeId: string
    members: {
      userId: string
      name?: string
      role: "owner" | "member"
      joinedAt: number
    }[]
    createdAt: number
    receipts?: {
      token?: string
      autoAdd?: boolean
      confirmation?: {
        code?: string
        link?: string
        at: number
      }
    }
  }
}
POST/v1/me/food/home/invites

An invitation link into your household, good for a week.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X POST 'https://api.cactive.com.au/v1/me/food/home/invites' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 201

{
  invite: {
    code: string
    url: string
    expiresAt: number
  }
}
GET/v1/me/food/home/invites/:code

What an invitation is for: the household's name, who invited you and how many are in it.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:read (when actor.type === "user")
Get an API key

Path parameters

  • code

    Mirage invite code (8 letters and digits); under me/food a household invitation's code (from its link).

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:read on a key made by a person.
curl 'https://api.cactive.com.au/v1/me/food/home/invites/{code}' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  invite: {
    homeName: string
    invitedBy: string
    members: number
  }
}
POST/v1/me/food/home/invites/:code/accept

Joins the household (your own waits for you; refused while yours has others in it).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Path parameters

  • code

    Mirage invite code (8 letters and digits); under me/food a household invitation's code (from its link).

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X POST 'https://api.cactive.com.au/v1/me/food/home/invites/{code}/accept' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  home: {
    homeId: string
    name: string
    members: {
      userId: string
      name?: string
      role: "owner" | "member"
      joinedAt: number
    }[]
    createdAt: number
    receipts?: {
      token?: string
      autoAdd?: boolean
      confirmation?: {
        code?: string
        link?: string
        at: number
      }
    }
  }
}
POST/v1/me/food/home/leave

Leaves the household, back to your own (its owner can't while others are in it).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X POST 'https://api.cactive.com.au/v1/me/food/home/leave' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  home: {
    homeId: string
    name: string
    members: {
      userId: string
      name?: string
      role: "owner" | "member"
      joinedAt: number
    }[]
    createdAt: number
    receipts?: {
      token?: string
      autoAdd?: boolean
      confirmation?: {
        code?: string
        link?: string
        at: number
      }
    }
  }
}
DELETE/v1/me/food/home/members/:userId

Removes someone from your household (its owner only).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Path parameters

  • userId

    A member's user id (usr_…).

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X DELETE 'https://api.cactive.com.au/v1/me/food/home/members/{userId}' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  home: {
    members: {
      userId: string
      name?: string
      role: "owner" | "member"
      joinedAt: number
    }[]
    homeId: string
    name: string
    createdAt: number
    receipts?: {
      token?: string
      autoAdd?: boolean
      confirmation?: {
        code?: string
        link?: string
        at: number
      }
    }
  }
}
GET/v1/me/food/recipes

The person's recipes and their household's shared ones as cards, searched and filtered (limit: at most 1000, 200 by default).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:read (when actor.type === "user")
Get an API key

Query parameters

  • qstring

    Up to 200 characters.

  • cuisinestring

    Up to 40 characters.

  • coursestring

    Up to 40 characters.

  • dietstring

    Up to 40 characters.

  • tagstring

    Up to 40 characters.

  • withoutstring

    Up to 200 characters.

  • maxMinutesinteger

    1–10000. Coerced from a string.

  • ingredientstring

    Up to 60 characters.

  • favourites"1" | "true"
  • collectionIdstring

    Up to 40 characters.

  • sort"recent" | "title" | "rating" | "cooked" | "quick"
  • household"1" | "true" | "0" | "false"
  • limitinteger

    1–1000. Coerced from a string.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:read on a key made by a person.
curl 'https://api.cactive.com.au/v1/me/food/recipes' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  recipes: {
    createdAt: number
    updatedAt: number
    title: string
    tags: string[]
    ownerId: string
    shared?: boolean
    favourite?: boolean
    recipeId: string
    servings: number
    totalMinutes?: number
    cuisines: string[]
    courses: string[]
    rating?: number
    household: boolean
    cookedCount: number
    lastCookedAt?: number
    diets: string[]
    allergens: string[]
    kcalPerServing?: number
    ingredientIds: string[]
    amounts?: {
      [key: string]: {
        g?: number
        ml?: number
        each?: number
        minor?: true
      }
    }
    measuredLines?: number
    image?: {
      imageId: string
      versionId?: string
      mime?: string
      width?: number
      height?: number
      alt?: string
      url: string
      thumbUrl: string
    }
  }[]
  total: number
}
POST/v1/me/food/recipes

Adds a recipe. Ingredients and steps may be text (one ingredient per line; steps by paragraph), which Food reads; imageUrls are copied in by the worker.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Request body

  • titleany JSONrequired
  • descriptionany JSON
  • servingsinteger

    1–1000.

  • yieldLabelany JSON
  • prepMinutesinteger

    0–43200.

  • cookMinutesinteger

    0–43200.

  • totalMinutesinteger

    0–43200.

  • ingredientsobject[] | any JSON

    Up to 150 items.

  • stepsobject[] | any JSON

    Up to 100 items.

  • cuisines[]

    Up to 5 items.

  • courses[]

    Up to 6 items.

  • claimedDiets[]

    Up to 10 items.

  • tagsstring[]

    Up to 30 items. Each 1–40 characters, matches ^[\p{L}\p{N}][\p{L}\p{N} '&-]*$, trimmed, lowercased.

  • difficulty"easy" | "medium" | "hard"or null
  • spoons"au" | "us"
  • sourceobject
  • source.kind"manual" | "web" | "photo" | "text" | "melt" | "paprika" | "mela" | "crouton" | "copymethat" | "assistant" | "copy"required
  • source.urlstring

    Up to 2,000 characters. URL.

  • source.nameany JSON
  • source.authorany JSON
  • notesstring

    Up to 20,000 characters.

  • ratingintegeror null

    1–5.

  • favouriteboolean
  • householdboolean
  • imagesobject[]

    Up to 10 items.

  • images[].imageIdstringrequired

    Up to 60 characters.

  • images[].versionIdstring

    Up to 60 characters.

  • images[].mimestring

    Matches ^image\/(jpeg|png|webp|gif)$.

  • images[].widthinteger
  • images[].heightinteger
  • images[].altany JSON
  • imageUrlsstring[]

    Up to 10 items. Each up to 2,000 characters, URL.

Also checked: Unknown fields are rejected.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X POST 'https://api.cactive.com.au/v1/me/food/recipes' \
  -H "Authorization: Bearer $CACTIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "title": {}
  }'
Send it from this page with your session or a key.

Response 201

{
  recipe: {
    version: number
    createdAt: number
    updatedAt: number
    title: string
    description?: string
    source?: {
      kind: "text" | "photo" | "web" | "manual" | "melt" | "paprika" | "mela" | "crouton" | "copymethat" | "assistant" | "copy"
      url?: string
      name?: string
      author?: string
    }
    tags: string[]
    ownerId: string
    steps: {
      id: string
      section?: string
      text: string
      timers?: {
        seconds: number
        label?: string
      }[]
    }[]
    favourite?: boolean
    recipeId: string
    servings: number
    yieldLabel?: string
    prepMinutes?: number
    cookMinutes?: number
    totalMinutes?: number
    ingredients: {
      id: string
      section?: string
      quantity?: number
      quantityMax?: number
      unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
      item: string
      note?: string
      ingredientId?: string
      optional?: boolean
    }[]
    cuisines: string[]
    courses: string[]
    claimedDiets: string[]
    difficulty?: "medium" | "easy" | "hard"
    spoons: "au" | "us"
    notes?: string
    rating?: number
    household: boolean
    cookedCount: number
    lastCookedAt?: number
    images: {
      imageId: string
      versionId?: string
      mime?: string
      width?: number
      height?: number
      alt?: string
      url: string
      thumbUrl: string
    }[]
    nutrition: {
      perServing: {
        kj: number
        kcal: number
        protein: number
        fat: number
        saturatedFat: number
        carbs: number
        sugars: number
        fibre: number
        sodium: number
      }
      total: {
        kj: number
        kcal: number
        protein: number
        fat: number
        saturatedFat: number
        carbs: number
        sugars: number
        fibre: number
        sodium: number
      }
      coverage: number
      unmatched: string[]
    }
    allergens: string[]
    diets: string[]
    access: "owner" | "household" | "public"
    ownerName?: string
    publicUrl?: string
    cost?: {
      total: number
      perServing: number
      coverage: number
      priced: number
      measured: number
    }
  }
}
GET/v1/me/food/recipes/:recipeId

A recipe in full, with signed picture links, nutrition per serving, allergens, diets and your access (owner, household).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:read (when actor.type === "user")
Get an API key

Path parameters

  • recipeId

    A recipe's id (rcp_…).

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:read on a key made by a person.
curl 'https://api.cactive.com.au/v1/me/food/recipes/{recipeId}' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  recipe: {
    version: number
    createdAt: number
    updatedAt: number
    title: string
    description?: string
    source?: {
      kind: "text" | "photo" | "web" | "manual" | "melt" | "paprika" | "mela" | "crouton" | "copymethat" | "assistant" | "copy"
      url?: string
      name?: string
      author?: string
    }
    tags: string[]
    ownerId: string
    steps: {
      id: string
      section?: string
      text: string
      timers?: {
        seconds: number
        label?: string
      }[]
    }[]
    favourite?: boolean
    recipeId: string
    servings: number
    yieldLabel?: string
    prepMinutes?: number
    cookMinutes?: number
    totalMinutes?: number
    ingredients: {
      id: string
      section?: string
      quantity?: number
      quantityMax?: number
      unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
      item: string
      note?: string
      ingredientId?: string
      optional?: boolean
    }[]
    cuisines: string[]
    courses: string[]
    claimedDiets: string[]
    difficulty?: "medium" | "easy" | "hard"
    spoons: "au" | "us"
    notes?: string
    rating?: number
    household: boolean
    cookedCount: number
    lastCookedAt?: number
    images: {
      imageId: string
      versionId?: string
      mime?: string
      width?: number
      height?: number
      alt?: string
      url: string
      thumbUrl: string
    }[]
    nutrition: {
      perServing: {
        kj: number
        kcal: number
        protein: number
        fat: number
        saturatedFat: number
        carbs: number
        sugars: number
        fibre: number
        sodium: number
      }
      total: {
        kj: number
        kcal: number
        protein: number
        fat: number
        saturatedFat: number
        carbs: number
        sugars: number
        fibre: number
        sodium: number
      }
      coverage: number
      unmatched: string[]
    }
    allergens: string[]
    diets: string[]
    access: "owner" | "household" | "public"
    ownerName?: string
    publicUrl?: string
    cost?: {
      total: number
      perServing: number
      coverage: number
      priced: number
      measured: number
    }
  }
}
PATCH/v1/me/food/recipes/:recipeId

Changes a recipe of the person's (version: refused with 409 when it changed meanwhile).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Path parameters

  • recipeId

    A recipe's id (rcp_…).

Request body

  • titleany JSON
  • descriptionany JSON
  • servingsinteger

    1–1000.

  • yieldLabelany JSON
  • prepMinutesinteger

    0–43200.

  • cookMinutesinteger

    0–43200.

  • totalMinutesinteger

    0–43200.

  • ingredientsobject[] | any JSON

    Up to 150 items.

  • stepsobject[] | any JSON

    Up to 100 items.

  • cuisines[]

    Up to 5 items.

  • courses[]

    Up to 6 items.

  • claimedDiets[]

    Up to 10 items.

  • tagsstring[]

    Up to 30 items. Each 1–40 characters, matches ^[\p{L}\p{N}][\p{L}\p{N} '&-]*$, trimmed, lowercased.

  • difficulty"easy" | "medium" | "hard"or null
  • spoons"au" | "us"
  • sourceobject
  • source.kind"manual" | "web" | "photo" | "text" | "melt" | "paprika" | "mela" | "crouton" | "copymethat" | "assistant" | "copy"required
  • source.urlstring

    Up to 2,000 characters. URL.

  • source.nameany JSON
  • source.authorany JSON
  • notesstring

    Up to 20,000 characters.

  • ratingintegeror null

    1–5.

  • favouriteboolean
  • householdboolean
  • imagesobject[]

    Up to 10 items.

  • images[].imageIdstringrequired

    Up to 60 characters.

  • images[].versionIdstring

    Up to 60 characters.

  • images[].mimestring

    Matches ^image\/(jpeg|png|webp|gif)$.

  • images[].widthinteger
  • images[].heightinteger
  • images[].altany JSON
  • imageUrlsstring[]

    Up to 10 items. Each up to 2,000 characters, URL.

  • versioninteger

    ≥ 0.

Also checked: Unknown fields are rejected. Unknown fields are rejected.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X PATCH 'https://api.cactive.com.au/v1/me/food/recipes/{recipeId}' \
  -H "Authorization: Bearer $CACTIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "title": {},
    "description": {},
    "servings": 1
  }'
Send it from this page with your session or a key.

Response 200

{
  recipe: {
    version: number
    createdAt: number
    updatedAt: number
    title: string
    description?: string
    source?: {
      kind: "text" | "photo" | "web" | "manual" | "melt" | "paprika" | "mela" | "crouton" | "copymethat" | "assistant" | "copy"
      url?: string
      name?: string
      author?: string
    }
    tags: string[]
    ownerId: string
    steps: {
      id: string
      section?: string
      text: string
      timers?: {
        seconds: number
        label?: string
      }[]
    }[]
    favourite?: boolean
    recipeId: string
    servings: number
    yieldLabel?: string
    prepMinutes?: number
    cookMinutes?: number
    totalMinutes?: number
    ingredients: {
      id: string
      section?: string
      quantity?: number
      quantityMax?: number
      unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
      item: string
      note?: string
      ingredientId?: string
      optional?: boolean
    }[]
    cuisines: string[]
    courses: string[]
    claimedDiets: string[]
    difficulty?: "medium" | "easy" | "hard"
    spoons: "au" | "us"
    notes?: string
    rating?: number
    household: boolean
    cookedCount: number
    lastCookedAt?: number
    images: {
      imageId: string
      versionId?: string
      mime?: string
      width?: number
      height?: number
      alt?: string
      url: string
      thumbUrl: string
    }[]
    nutrition: {
      perServing: {
        kj: number
        kcal: number
        protein: number
        fat: number
        saturatedFat: number
        carbs: number
        sugars: number
        fibre: number
        sodium: number
      }
      total: {
        kj: number
        kcal: number
        protein: number
        fat: number
        saturatedFat: number
        carbs: number
        sugars: number
        fibre: number
        sodium: number
      }
      coverage: number
      unmatched: string[]
    }
    allergens: string[]
    diets: string[]
    access: "owner" | "household" | "public"
    ownerName?: string
    publicUrl?: string
    cost?: {
      total: number
      perServing: number
      coverage: number
      priced: number
      measured: number
    }
  }
}
DELETE/v1/me/food/recipes/:recipeId

Deletes a recipe of yours, its pictures (freeing their storage) and its public link.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Path parameters

  • recipeId

    A recipe's id (rcp_…).

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X DELETE 'https://api.cactive.com.au/v1/me/food/recipes/{recipeId}' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  recipeId: string
  deleted: boolean
}
POST/v1/me/food/recipes/:recipeId/copy

Copies a recipe your household shares into your own recipes (pictures copied into your storage).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Path parameters

  • recipeId

    A recipe's id (rcp_…).

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X POST 'https://api.cactive.com.au/v1/me/food/recipes/{recipeId}/copy' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 201

{
  recipe: {
    version: number
    createdAt: number
    updatedAt: number
    title: string
    description?: string
    source?: {
      kind: "text" | "photo" | "web" | "manual" | "melt" | "paprika" | "mela" | "crouton" | "copymethat" | "assistant" | "copy"
      url?: string
      name?: string
      author?: string
    }
    tags: string[]
    ownerId: string
    steps: {
      id: string
      section?: string
      text: string
      timers?: {
        seconds: number
        label?: string
      }[]
    }[]
    favourite?: boolean
    recipeId: string
    servings: number
    yieldLabel?: string
    prepMinutes?: number
    cookMinutes?: number
    totalMinutes?: number
    ingredients: {
      id: string
      section?: string
      quantity?: number
      quantityMax?: number
      unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
      item: string
      note?: string
      ingredientId?: string
      optional?: boolean
    }[]
    cuisines: string[]
    courses: string[]
    claimedDiets: string[]
    difficulty?: "medium" | "easy" | "hard"
    spoons: "au" | "us"
    notes?: string
    rating?: number
    household: boolean
    cookedCount: number
    lastCookedAt?: number
    images: {
      imageId: string
      versionId?: string
      mime?: string
      width?: number
      height?: number
      alt?: string
      url: string
      thumbUrl: string
    }[]
    nutrition: {
      perServing: {
        kj: number
        kcal: number
        protein: number
        fat: number
        saturatedFat: number
        carbs: number
        sugars: number
        fibre: number
        sodium: number
      }
      total: {
        kj: number
        kcal: number
        protein: number
        fat: number
        saturatedFat: number
        carbs: number
        sugars: number
        fibre: number
        sodium: number
      }
      coverage: number
      unmatched: string[]
    }
    allergens: string[]
    diets: string[]
    access: "owner" | "household" | "public"
    ownerName?: string
    publicUrl?: string
    cost?: {
      total: number
      perServing: number
      coverage: number
      priced: number
      measured: number
    }
  }
}
POST/v1/me/food/recipes/:recipeId/cook

Logs that the person cooked it, with a rating and note; logToHealth logs a serving to Health's nutrition (when they turned it on).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Path parameters

  • recipeId

    A recipe's id (rcp_…).

Request body

  • servingsinteger

    1–100.

  • ratinginteger

    1–5.

  • noteany JSON
  • atinteger
  • logToHealthboolean
  • leftoversobject
  • leftovers.portionsintegerrequired

    1–50.

  • leftovers.place"fridge" | "freezer"required
  • leftovers.useBystring

    Matches ^\d{4}-\d{2}-\d{2}$.

Also checked: Unknown fields are rejected.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X POST 'https://api.cactive.com.au/v1/me/food/recipes/{recipeId}/cook' \
  -H "Authorization: Bearer $CACTIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "servings": 1,
    "rating": 1,
    "note": {}
  }'
Send it from this page with your session or a key.

Response 201

{
  leftovers?: {
    itemId: string
    name: string
    ingredientId?: string
    quantity?: number
    unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
    place: "fridge" | "freezer" | "pantry"
    useBy?: string
    addedBy: string
    addedAt: number
    source?: "photo" | "manual" | "receipt" | "leftovers" | "barcode"
    barcode?: string
    leftover?: {
      recipeId: string
      title: string
      portions: number
      cookedOn: string
    }
  }
  health?: {
    logged: boolean
    error?: string
  }
  cook: {
    cookId: string
    recipeId: string
    title: string
    userId: string
    at: number
    servings?: number
    rating?: number
    note?: string
    loggedToHealth?: boolean
  }
}
POST/v1/me/food/recipes/:recipeId/notes

Saves the recipe as a Notes page in one of the person's orgs (where they can write Notes).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:read (when actor.type === "user")
Get an API key

Path parameters

  • recipeId

    A recipe's id (rcp_…).

Request body

  • orgIdstringrequired

    1–64 characters.

  • parentIdstring

    Up to 64 characters.

Errors

  • 400Parent page not found.
  • 400The parent page is in the trash.
  • 400Unknown property.
  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:read on a key made by a person.
  • 403You can't add pages to Notes in that organization.
  • 404Page not found
  • 409This page is in the trash. Restore it to edit.
  • 413Pages can be up to 1 MB.
curl -X POST 'https://api.cactive.com.au/v1/me/food/recipes/{recipeId}/notes' \
  -H "Authorization: Bearer $CACTIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "orgId": "<orgId>"
  }'
Send it from this page with your session or a key.

Response 201

{
  page: {
    orgId: string
    pageId: string
    title: string
  }
}
POST/v1/me/food/public/:token/copy

Copies a recipe shared by public link into your own recipes.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Path parameters

  • token

    A secret from a link: an issue automation rule's incoming-webhook token (shown once when issued), a map's share link, a notification recipient's confirm and unsubscribe link, a Drive public link (/l/<token>), a Vehicles drive's share link, or a Mirage interaction's token (itk_…, sent with the interaction, good for 15 minutes), or the token in the link to a file of a message Mirage sent to Discord, or a Marketing link's sealed token (a tracked click, the open pixel, unsubscribe and the preference centre, a double opt-in confirmation); or a Food recipe's public link (/r/<token>) or a household's calendar feed.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X POST 'https://api.cactive.com.au/v1/me/food/public/{token}/copy' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 201

{
  recipe: {
    version: number
    createdAt: number
    updatedAt: number
    title: string
    description?: string
    source?: {
      kind: "text" | "photo" | "web" | "manual" | "melt" | "paprika" | "mela" | "crouton" | "copymethat" | "assistant" | "copy"
      url?: string
      name?: string
      author?: string
    }
    tags: string[]
    ownerId: string
    steps: {
      id: string
      section?: string
      text: string
      timers?: {
        seconds: number
        label?: string
      }[]
    }[]
    favourite?: boolean
    recipeId: string
    servings: number
    yieldLabel?: string
    prepMinutes?: number
    cookMinutes?: number
    totalMinutes?: number
    ingredients: {
      id: string
      section?: string
      quantity?: number
      quantityMax?: number
      unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
      item: string
      note?: string
      ingredientId?: string
      optional?: boolean
    }[]
    cuisines: string[]
    courses: string[]
    claimedDiets: string[]
    difficulty?: "medium" | "easy" | "hard"
    spoons: "au" | "us"
    notes?: string
    rating?: number
    household: boolean
    cookedCount: number
    lastCookedAt?: number
    images: {
      imageId: string
      versionId?: string
      mime?: string
      width?: number
      height?: number
      alt?: string
      url: string
      thumbUrl: string
    }[]
    nutrition: {
      perServing: {
        kj: number
        kcal: number
        protein: number
        fat: number
        saturatedFat: number
        carbs: number
        sugars: number
        fibre: number
        sodium: number
      }
      total: {
        kj: number
        kcal: number
        protein: number
        fat: number
        saturatedFat: number
        carbs: number
        sugars: number
        fibre: number
        sodium: number
      }
      coverage: number
      unmatched: string[]
    }
    allergens: string[]
    diets: string[]
    access: "owner" | "household" | "public"
    ownerName?: string
    publicUrl?: string
    cost?: {
      total: number
      perServing: number
      coverage: number
      priced: number
      measured: number
    }
  }
}
GET/v1/me/food/history

What you've cooked, newest first, with ratings and notes (limit, 100 by default).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:read (when actor.type === "user")
Get an API key

Query parameters

  • limitstring

    Default 100.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:read on a key made by a person.
curl 'https://api.cactive.com.au/v1/me/food/history' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  cooked: {
    cookId: string
    recipeId: string
    title: string
    userId: string
    at: number
    servings?: number
    rating?: number
    note?: string
    loggedToHealth?: boolean
  }[]
}
POST/v1/me/food/images

Keeps a picture (base64 JPEG, PNG, WebP or GIF, at most 8 MB) in the person's Food drive, metadata removed; use the answer in a recipe's images.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Request body (up to 10,240 KB)

  • datastringrequired

    10–12,000,000 characters.

  • namestring

    Up to 100 characters.

  • altstring

    Up to 300 characters.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
  • 413That's too large. Send pictures of at most 8 MB, four at a time.
curl -X POST 'https://api.cactive.com.au/v1/me/food/images' \
  -H "Authorization: Bearer $CACTIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "data": "example"
  }'
Send it from this page with your session or a key.

Response 201

{
  image?: {
    imageId: string
    versionId?: string
    mime?: string
    width?: number
    height?: number
    alt?: string
    url: string
    thumbUrl: string
  }
}
GET/v1/me/food/collections

Your collections, with their recipes in order and their groups.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:read (when actor.type === "user")
Get an API key

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:read on a key made by a person.
curl 'https://api.cactive.com.au/v1/me/food/collections' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  collections: {
    collectionId: string
    ownerId: string
    name: string
    description?: string
    recipeIds: string[]
    groups?: {
      name: string
      recipeIds: string[]
    }[]
    coverRecipeId?: string
    createdAt: number
    updatedAt: number
  }[]
}
POST/v1/me/food/collections

A new collection, optionally with recipes and named groups.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Request body

  • nameany JSONrequired
  • descriptionany JSON
  • recipeIdsstring[]

    Up to 2,000 items. Each up to 40 characters.

  • groupsobject[]

    Up to 50 items.

  • groups[].nameany JSONrequired
  • groups[].recipeIdsstring[]required

    Up to 2,000 items. Each up to 40 characters.

Also checked: Unknown fields are rejected.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X POST 'https://api.cactive.com.au/v1/me/food/collections' \
  -H "Authorization: Bearer $CACTIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "name": {}
  }'
Send it from this page with your session or a key.

Response 201

{
  collection: {
    collectionId: string
    ownerId: string
    name: string
    description?: string
    recipeIds: string[]
    groups?: {
      name: string
      recipeIds: string[]
    }[]
    coverRecipeId?: string
    createdAt: number
    updatedAt: number
  }
}
PATCH/v1/me/food/collections/:collectionId

Renames a collection or changes its recipes (add, remove, or the whole recipeIds in order).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Path parameters

  • collectionId

    A Food collection's id (fcl_…).

Request body

  • nameany JSON
  • descriptionany JSON
  • recipeIdsstring[]

    Up to 2,000 items. Each up to 40 characters.

  • groupsobject[]

    Up to 50 items.

  • groups[].nameany JSONrequired
  • groups[].recipeIdsstring[]required

    Up to 2,000 items. Each up to 40 characters.

  • addstring[]

    Up to 500 items. Each up to 40 characters.

  • removestring[]

    Up to 500 items. Each up to 40 characters.

Also checked: Unknown fields are rejected.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X PATCH 'https://api.cactive.com.au/v1/me/food/collections/{collectionId}' \
  -H "Authorization: Bearer $CACTIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "name": {},
    "description": {},
    "recipeIds": [
      "example"
    ]
  }'
Send it from this page with your session or a key.

Response 200

{
  collection: {
    collectionId: string
    ownerId: string
    name: string
    description?: string
    recipeIds: string[]
    groups?: {
      name: string
      recipeIds: string[]
    }[]
    coverRecipeId?: string
    createdAt: number
    updatedAt: number
  }
}
DELETE/v1/me/food/collections/:collectionId

Deletes a collection (its recipes stay).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Path parameters

  • collectionId

    A Food collection's id (fcl_…).

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X DELETE 'https://api.cactive.com.au/v1/me/food/collections/{collectionId}' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  collectionId: string
  deleted: boolean
}
GET/v1/me/food/plan

The household's meals between two days (at most 92).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:read (when actor.type === "user")
Get an API key

Query parameters

  • fromstringrequired

    Matches ^\d{4}-\d{2}-\d{2}$.

  • tostringrequired

    Matches ^\d{4}-\d{2}-\d{2}$.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:read on a key made by a person.
curl 'https://api.cactive.com.au/v1/me/food/plan?from=example&to=example' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  entries: {
    leftover?: {
      itemId: string
      cookedOn: string
    }
    entryId: string
    homeId: string
    day: string
    meal: "breakfast" | "lunch" | "dinner" | "snack"
    recipeId?: string
    title: string
    servings?: number
    note?: string
    addedBy: string
    calendarEventId?: string
    cooked?: boolean
    createdAt: number
  }[]
}
POST/v1/me/food/plan

Puts a meal on the household's plan: a recipe, or a note ("Leftovers").

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Request body

  • daystringrequired

    Matches ^\d{4}-\d{2}-\d{2}$.

  • mealanyrequired
  • recipeIdstring

    Up to 40 characters.

  • titleany JSON
  • servingsinteger

    1–100.

  • noteany JSON
  • leftoverItemIdstring

    Up to 40 characters.

Also checked: Unknown fields are rejected. Choose a recipe or write what's on.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X POST 'https://api.cactive.com.au/v1/me/food/plan' \
  -H "Authorization: Bearer $CACTIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "day": "example",
    "meal": "example"
  }'
Send it from this page with your session or a key.

Response 201

{
  entry: {
    leftover?: {
      itemId: string
      cookedOn: string
    }
    entryId: string
    homeId: string
    day: string
    meal: "breakfast" | "lunch" | "dinner" | "snack"
    recipeId?: string
    title: string
    servings?: number
    note?: string
    addedBy: string
    calendarEventId?: string
    cooked?: boolean
    createdAt: number
  }
}
PATCH/v1/me/food/plan/:entryId

Moves or changes a meal (from: the day it's on now, which saves a lookup).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Path parameters

  • entryId

    A meal on the plan (fpe_…); under vehicles an entry of a car's log made by hand (vlg_…), as the log lists it.

Request body

  • daystring

    Matches ^\d{4}-\d{2}-\d{2}$.

  • meal"breakfast" | "lunch" | "dinner" | "snack"
  • recipeIdstring

    Up to 40 characters.

  • titlestring

    Up to 200 characters.

  • servingsinteger

    1–100.

  • notestring

    Up to 500 characters.

  • cookedboolean
  • fromstring

    Matches ^\d{4}-\d{2}-\d{2}$.

Also checked: Unknown fields are rejected.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X PATCH 'https://api.cactive.com.au/v1/me/food/plan/{entryId}' \
  -H "Authorization: Bearer $CACTIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "day": "example",
    "meal": "breakfast",
    "recipeId": "<recipeId>"
  }'
Send it from this page with your session or a key.

Response 200

{
  entry: {
    leftover?: {
      itemId: string
      cookedOn: string
    }
    entryId: string
    homeId: string
    day: string
    meal: "breakfast" | "lunch" | "dinner" | "snack"
    recipeId?: string
    title: string
    servings?: number
    note?: string
    addedBy: string
    calendarEventId?: string
    cooked?: boolean
    createdAt: number
  }
}
DELETE/v1/me/food/plan/:entryId

Takes a meal off the plan (day: the day it's on, which saves a lookup).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Path parameters

  • entryId

    A meal on the plan (fpe_…); under vehicles an entry of a car's log made by hand (vlg_…), as the log lists it.

Query parameters

  • daystring

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X DELETE 'https://api.cactive.com.au/v1/me/food/plan/{entryId}' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  entry: {
    leftover?: {
      itemId: string
      cookedOn: string
    }
    entryId: string
    homeId: string
    day: string
    meal: "breakfast" | "lunch" | "dinner" | "snack"
    recipeId?: string
    title: string
    servings?: number
    note?: string
    addedBy: string
    calendarEventId?: string
    cooked?: boolean
    createdAt: number
  }
}
GET/v1/me/food/plan/feed

The household's private calendar feed link (url, and webcal for calendar apps).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:read (when actor.type === "user")
Get an API key

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:read on a key made by a person.
curl 'https://api.cactive.com.au/v1/me/food/plan/feed' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  feed: {
    url: string
    webcal: string
  }
}
POST/v1/me/food/plan/feed/rotate

Replaces the calendar feed link; the old one stops working.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X POST 'https://api.cactive.com.au/v1/me/food/plan/feed/rotate' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  feed: {
    url: string
    webcal: string
  }
}
POST/v1/me/food/plan/suggest

Proposes (or with apply, plans) meals for the days ahead from the suggestions.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Request body

  • fromstring

    Matches ^\d{4}-\d{2}-\d{2}$.

  • daysinteger

    1–14.

  • meal"breakfast" | "lunch" | "dinner" | "snack"
  • maxMinutesinteger

    5–600.

  • dietsstring[]

    Up to 10 items. Each up to 40 characters.

  • budgetnumber

    1–100000.

  • applyboolean

Also checked: Unknown fields are rejected.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X POST 'https://api.cactive.com.au/v1/me/food/plan/suggest' \
  -H "Authorization: Bearer $CACTIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "from": "example",
    "days": 1,
    "meal": "breakfast"
  }'
Send it from this page with your session or a key.

Response 200

{
  budget?: number
  cost?: {
    total: number
    priced: number
    nights: number
  }
  from: string
  days: number
  meal: "breakfast" | "lunch" | "dinner" | "snack"
  applied: boolean
  planned: {
    cost?: number
    day: string
    meal: "breakfast" | "lunch" | "dinner" | "snack"
    recipeId: string
    title: string
    totalMinutes?: number
    reasons: string[]
  }[]
  skippedDays: string[]
  unfilled: string[]
}
POST/v1/me/food/plan/calendar

Puts planned meals on a Mail calendar of the person's (events at meal times, linking back).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Request body

  • orgIdstringrequired

    1–64 characters.

  • mailboxIdstringrequired

    1–64 characters.

  • calendarIdstringrequired

    1–64 characters.

  • fromstringrequired

    Matches ^\d{4}-\d{2}-\d{2}$.

  • tostringrequired

    Matches ^\d{4}-\d{2}-\d{2}$.

  • timeZonestringrequired

    1–64 characters.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
  • 403You can't add events to calendars in that organization.
  • 404Mailbox not found
curl -X POST 'https://api.cactive.com.au/v1/me/food/plan/calendar' \
  -H "Authorization: Bearer $CACTIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "orgId": "<orgId>",
    "mailboxId": "<mailboxId>",
    "calendarId": "<calendarId>",
    "from": "example",
    "to": "example",
    "timeZone": "example"
  }'
Send it from this page with your session or a key.

Response 200

{
  added: number
}
GET/v1/me/food/lists

The household's shopping lists, most recently changed first.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:read (when actor.type === "user")
Get an API key

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:read on a key made by a person.
curl 'https://api.cactive.com.au/v1/me/food/lists' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  lists: {
    listId: string
    homeId: string
    name: string
    items: {
      itemId: string
      name: string
      quantity?: number
      unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
      amount?: string
      aisle: "none" | "other" | "household" | "meat" | "dairy" | "breakfast" | "baking" | "produce" | "bakery" | "seafood" | "deli" | "chilled" | "pasta" | "canned" | "condiments" | "oils" | "spices" | "nuts" | "spreads" | "frozen" | "drinks"
      ingredientId?: string
      note?: string
      checked: boolean
      forRecipes?: string[]
      addedBy: string
      addedAt: number
      checkedBy?: string
    }[]
    createdAt: number
    updatedAt: number
    version: number
  }[]
}
POST/v1/me/food/lists

A new list: empty, from the plan between two days, or from recipes at given servings (merged by ingredient, by aisle, without the pantry).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Request body

  • namestring

    Up to 100 characters.

  • fromPlanobject
  • fromPlan.fromstringrequired

    Matches ^\d{4}-\d{2}-\d{2}$.

  • fromPlan.tostringrequired

    Matches ^\d{4}-\d{2}-\d{2}$.

  • fromRecipesobject[]

    Up to 50 items.

  • fromRecipes[].recipeIdstringrequired

    Up to 40 characters.

  • fromRecipes[].servingsinteger

    1–100.

  • skipPantryboolean
  • withStaplesboolean

Also checked: Unknown fields are rejected.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X POST 'https://api.cactive.com.au/v1/me/food/lists' \
  -H "Authorization: Bearer $CACTIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Example",
    "fromPlan": {
      "from": "example",
      "to": "example"
    },
    "fromRecipes": [
      {
        "recipeId": "<recipeId>"
      }
    ]
  }'
Send it from this page with your session or a key.

Response 201

{
  list: {
    listId: string
    homeId: string
    name: string
    items: {
      itemId: string
      name: string
      quantity?: number
      unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
      amount?: string
      aisle: "none" | "other" | "household" | "meat" | "dairy" | "breakfast" | "baking" | "produce" | "bakery" | "seafood" | "deli" | "chilled" | "pasta" | "canned" | "condiments" | "oils" | "spices" | "nuts" | "spreads" | "frozen" | "drinks"
      ingredientId?: string
      note?: string
      checked: boolean
      forRecipes?: string[]
      addedBy: string
      addedAt: number
      checkedBy?: string
    }[]
    createdAt: number
    updatedAt: number
    version: number
  }
}
GET/v1/me/food/lists/:listId

A shopping list with its items (aisle, amount, ticked, the recipes they're for).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:read (when actor.type === "user")
Get an API key

Path parameters

  • listId

    Saved map id (mls_…); under marketing a list (mkl_…); under me/food a shopping list (fls_…).

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:read on a key made by a person.
curl 'https://api.cactive.com.au/v1/me/food/lists/{listId}' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  list: {
    listId: string
    homeId: string
    name: string
    items: {
      itemId: string
      name: string
      quantity?: number
      unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
      amount?: string
      aisle: "none" | "other" | "household" | "meat" | "dairy" | "breakfast" | "baking" | "produce" | "bakery" | "seafood" | "deli" | "chilled" | "pasta" | "canned" | "condiments" | "oils" | "spices" | "nuts" | "spreads" | "frozen" | "drinks"
      ingredientId?: string
      note?: string
      checked: boolean
      forRecipes?: string[]
      addedBy: string
      addedAt: number
      checkedBy?: string
    }[]
    createdAt: number
    updatedAt: number
    version: number
  }
  prices: {
    [key: string]: {
      day: string
      paid: number
      storeName: string
    }
  }
}
PATCH/v1/me/food/lists/:listId

Renames a list.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Path parameters

  • listId

    Saved map id (mls_…); under marketing a list (mkl_…); under me/food a shopping list (fls_…).

Request body

  • namestringrequired

    1–100 characters.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X PATCH 'https://api.cactive.com.au/v1/me/food/lists/{listId}' \
  -H "Authorization: Bearer $CACTIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Example"
  }'
Send it from this page with your session or a key.

Response 200

{
  list: {
    listId: string
    homeId: string
    name: string
    items: {
      itemId: string
      name: string
      quantity?: number
      unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
      amount?: string
      aisle: "none" | "other" | "household" | "meat" | "dairy" | "breakfast" | "baking" | "produce" | "bakery" | "seafood" | "deli" | "chilled" | "pasta" | "canned" | "condiments" | "oils" | "spices" | "nuts" | "spreads" | "frozen" | "drinks"
      ingredientId?: string
      note?: string
      checked: boolean
      forRecipes?: string[]
      addedBy: string
      addedAt: number
      checkedBy?: string
    }[]
    createdAt: number
    updatedAt: number
    version: number
  }
}
DELETE/v1/me/food/lists/:listId

Deletes a list.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Path parameters

  • listId

    Saved map id (mls_…); under marketing a list (mkl_…); under me/food a shopping list (fls_…).

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X DELETE 'https://api.cactive.com.au/v1/me/food/lists/{listId}' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  listId: string
  deleted: boolean
}
POST/v1/me/food/lists/:listId/items

Adds items to a list (their aisle from the ingredient when not given).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Path parameters

  • listId

    Saved map id (mls_…); under marketing a list (mkl_…); under me/food a shopping list (fls_…).

Request body

  • itemsobject[]required

    1–100 items.

  • items[].nameany JSONrequired
  • items[].quantitynumber

    0–100000.

  • items[].unitany
  • items[].amountany JSON
  • items[].aisleany
  • items[].noteany JSON

Also checked: Unknown fields are rejected.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X POST 'https://api.cactive.com.au/v1/me/food/lists/{listId}/items' \
  -H "Authorization: Bearer $CACTIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "items": [
      {
        "name": {}
      }
    ]
  }'
Send it from this page with your session or a key.

Response 201

{
  list: {
    listId: string
    homeId: string
    name: string
    items: {
      itemId: string
      name: string
      quantity?: number
      unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
      amount?: string
      aisle: "none" | "other" | "household" | "meat" | "dairy" | "breakfast" | "baking" | "produce" | "bakery" | "seafood" | "deli" | "chilled" | "pasta" | "canned" | "condiments" | "oils" | "spices" | "nuts" | "spreads" | "frozen" | "drinks"
      ingredientId?: string
      note?: string
      checked: boolean
      forRecipes?: string[]
      addedBy: string
      addedAt: number
      checkedBy?: string
    }[]
    createdAt: number
    updatedAt: number
    version: number
  }
}
POST/v1/me/food/lists/:listId/recipes

Adds recipes' ingredients to a list (merged with what's on it).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Path parameters

  • listId

    Saved map id (mls_…); under marketing a list (mkl_…); under me/food a shopping list (fls_…).

Request body

  • recipesobject[]required

    1–50 items.

  • recipes[].recipeIdstringrequired

    Up to 40 characters.

  • recipes[].servingsinteger

    1–100.

  • skipPantryboolean

Also checked: Unknown fields are rejected.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X POST 'https://api.cactive.com.au/v1/me/food/lists/{listId}/recipes' \
  -H "Authorization: Bearer $CACTIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "recipes": [
      {
        "recipeId": "<recipeId>"
      }
    ]
  }'
Send it from this page with your session or a key.

Response 200

{
  list: {
    listId: string
    homeId: string
    name: string
    items: {
      itemId: string
      name: string
      quantity?: number
      unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
      amount?: string
      aisle: "none" | "other" | "household" | "meat" | "dairy" | "breakfast" | "baking" | "produce" | "bakery" | "seafood" | "deli" | "chilled" | "pasta" | "canned" | "condiments" | "oils" | "spices" | "nuts" | "spreads" | "frozen" | "drinks"
      ingredientId?: string
      note?: string
      checked: boolean
      forRecipes?: string[]
      addedBy: string
      addedAt: number
      checkedBy?: string
    }[]
    createdAt: number
    updatedAt: number
    version: number
  }
}
PATCH/v1/me/food/lists/:listId/items/:itemId

Ticks an item (checked) or changes it; two people ticking at once both land.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Path parameters

  • listId

    Saved map id (mls_…); under marketing a list (mkl_…); under me/food a shopping list (fls_…).

  • itemId

    Drive file (fil_…) or folder (fld_…) id, or a drive id for its top folder; under me/food a shopping list item (fli_…) or something in the pantry (fpn_…).

Request body

  • nameany JSON
  • quantitynumber

    0–100000.

  • unitany
  • amountany JSON
  • aisleany
  • noteany JSON
  • checkedboolean

Also checked: Unknown fields are rejected. Unknown fields are rejected.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X PATCH 'https://api.cactive.com.au/v1/me/food/lists/{listId}/items/{itemId}' \
  -H "Authorization: Bearer $CACTIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "name": {},
    "quantity": 1,
    "unit": "example"
  }'
Send it from this page with your session or a key.

Response 200

{
  list: {
    listId: string
    homeId: string
    name: string
    items: {
      itemId: string
      name: string
      quantity?: number
      unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
      amount?: string
      aisle: "none" | "other" | "household" | "meat" | "dairy" | "breakfast" | "baking" | "produce" | "bakery" | "seafood" | "deli" | "chilled" | "pasta" | "canned" | "condiments" | "oils" | "spices" | "nuts" | "spreads" | "frozen" | "drinks"
      ingredientId?: string
      note?: string
      checked: boolean
      forRecipes?: string[]
      addedBy: string
      addedAt: number
      checkedBy?: string
    }[]
    createdAt: number
    updatedAt: number
    version: number
  }
}
POST/v1/me/food/lists/:listId/items/remove

Removes items by id, or every ticked one ({ "checked": true }).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Path parameters

  • listId

    Saved map id (mls_…); under marketing a list (mkl_…); under me/food a shopping list (fls_…).

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X POST 'https://api.cactive.com.au/v1/me/food/lists/{listId}/items/remove' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  list: {
    listId: string
    homeId: string
    name: string
    items: {
      itemId: string
      name: string
      quantity?: number
      unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
      amount?: string
      aisle: "none" | "other" | "household" | "meat" | "dairy" | "breakfast" | "baking" | "produce" | "bakery" | "seafood" | "deli" | "chilled" | "pasta" | "canned" | "condiments" | "oils" | "spices" | "nuts" | "spreads" | "frozen" | "drinks"
      ingredientId?: string
      note?: string
      checked: boolean
      forRecipes?: string[]
      addedBy: string
      addedAt: number
      checkedBy?: string
    }[]
    createdAt: number
    updatedAt: number
    version: number
  }
}
GET/v1/me/food/pantry

What the household has in, soonest use-by first.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:read (when actor.type === "user")
Get an API key

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:read on a key made by a person.
curl 'https://api.cactive.com.au/v1/me/food/pantry' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  items: {
    itemId: string
    name: string
    ingredientId?: string
    quantity?: number
    unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
    place: "fridge" | "freezer" | "pantry"
    useBy?: string
    addedBy: string
    addedAt: number
    source?: "photo" | "manual" | "receipt" | "leftovers" | "barcode"
    barcode?: string
    leftover?: {
      recipeId: string
      title: string
      portions: number
      cookedOn: string
    }
  }[]
  prices: {
    [key: string]: {
      day: string
      paid: number
      storeName: string
    }
  }
}
POST/v1/me/food/pantry

Adds things to the household's pantry, fridge or freezer: placed by kind and given an estimated use-by unless given; merged into the same thing already there unless merge is false.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Request body

  • itemsobject[]required

    1–100 items.

  • items[].nameany JSONrequired
  • items[].quantitynumber

    0–100000.

  • items[].unitany
  • items[].place"pantry" | "fridge" | "freezer"
  • items[].useBystringor null

    Matches ^\d{4}-\d{2}-\d{2}$.

  • items[].ingredientIdstring

    Up to 60 characters.

  • items[].source"manual" | "barcode" | "photo" | "receipt" | "leftovers"
  • items[].barcodestring

    Matches ^\d{8,14}$.

  • items[].mergeboolean

Also checked: Unknown fields are rejected.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X POST 'https://api.cactive.com.au/v1/me/food/pantry' \
  -H "Authorization: Bearer $CACTIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "items": [
      {
        "name": {}
      }
    ]
  }'
Send it from this page with your session or a key.

Response 201

{
  items: {
    itemId: string
    name: string
    ingredientId?: string
    quantity?: number
    unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
    place: "fridge" | "freezer" | "pantry"
    useBy?: string
    addedBy: string
    addedAt: number
    source?: "photo" | "manual" | "receipt" | "leftovers" | "barcode"
    barcode?: string
    leftover?: {
      recipeId: string
      title: string
      portions: number
      cookedOn: string
    }
  }[]
}
GET/v1/me/food/pantry/use-soon

What needs using soon (within days, 3 by default) and the recipes that use the most of it.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:read (when actor.type === "user")
Get an API key

Query parameters

  • daysinteger

    1–14. Coerced from a string.

  • todaystring

    Matches ^\d{4}-\d{2}-\d{2}$.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:read on a key made by a person.
curl 'https://api.cactive.com.au/v1/me/food/pantry/use-soon' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  items: {
    itemId: string
    name: string
    ingredientId?: string
    quantity?: number
    unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
    place: "fridge" | "freezer" | "pantry"
    useBy?: string
    addedBy: string
    addedAt: number
    source?: "photo" | "manual" | "receipt" | "leftovers" | "barcode"
    barcode?: string
    leftover?: {
      recipeId: string
      title: string
      portions: number
      cookedOn: string
    }
  }[]
  recipes: {
    recipe: {
      createdAt: number
      updatedAt: number
      title: string
      tags: string[]
      ownerId: string
      shared?: boolean
      favourite?: boolean
      recipeId: string
      servings: number
      totalMinutes?: number
      cuisines: string[]
      courses: string[]
      rating?: number
      household: boolean
      cookedCount: number
      lastCookedAt?: number
      diets: string[]
      allergens: string[]
      kcalPerServing?: number
      ingredientIds: string[]
      amounts?: {
        [key: string]: {
          g?: number
          ml?: number
          each?: number
          minor?: true
        }
      }
      measuredLines?: number
      image?: {
        imageId: string
        versionId?: string
        mime?: string
        width?: number
        height?: number
        alt?: string
        url: string
        thumbUrl: string
      }
    }
    uses: string[]
  }[]
}
GET/v1/me/food/pantry/barcodes/:code

What a barcode is (the household's own answer, else Open Food Facts), as a pantry item to check; found: false when nobody knows it.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Path parameters

  • code

    Mirage invite code (8 letters and digits); under me/food a household invitation's code (from its link).

Query parameters

  • todaystring

    Matches ^\d{4}-\d{2}-\d{2}$.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl 'https://api.cactive.com.au/v1/me/food/pantry/barcodes/{code}' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  code: string
  found: true
  source: "household"
  item: {
    name: string
    ingredientId?: string
    quantity?: number
    unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
    place: "fridge" | "freezer" | "pantry"
    useBy?: string
    barcode?: string
    brand?: string
    mergeInto?: {
      itemId: string
      name: string
    }
  }
} | {
  code: string
  found: false
  source?: undefined
  item?: undefined
} | {
  code: string
  found: true
  source: "openfoodfacts"
  item: {
    name: string
    ingredientId?: string
    quantity?: number
    unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
    place: "fridge" | "freezer" | "pantry"
    useBy?: string
    barcode?: string
    brand?: string
    mergeInto?: {
      itemId: string
      name: string
    }
  }
}
PUT/v1/me/food/pantry/barcodes/:code

The household's own answer for a barcode (one nobody knew, or a correction).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Path parameters

  • code

    Mirage invite code (8 letters and digits); under me/food a household invitation's code (from its link).

Request body

  • namestringrequired

    1–120 characters. Trimmed.

  • ingredientIdstring

    Up to 60 characters.

  • quantitynumber

    0–100000.

  • unit"g" | "kg" | "ml" | "l"

Also checked: Unknown fields are rejected.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X PUT 'https://api.cactive.com.au/v1/me/food/pantry/barcodes/{code}' \
  -H "Authorization: Bearer $CACTIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Example"
  }'
Send it from this page with your session or a key.

Response 200

{
  barcode: {
    ingredientId?: string
    code: string
    name: string
  }
}
POST/v1/me/food/pantry/scans

Photos of a shelf, the fridge or a bench of shopping (base64, up to four), read by the model into items to check; poll the scan. Counts against the daily photo readings.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Request body (up to 10,240 KB)

  • photosstring[]required

    1–4 items. Each 10–12,000,000 characters.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
  • 413That's too large. Send pictures of at most 8 MB, four at a time.
curl -X POST 'https://api.cactive.com.au/v1/me/food/pantry/scans' \
  -H "Authorization: Bearer $CACTIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "photos": [
      "example"
    ]
  }'
Send it from this page with your session or a key.

Response 202

{
  scan: {
    createdAt: number
    error?: string
    items?: {
      name: string
      ingredientId?: string
      quantity?: number
      unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
      place: "fridge" | "freezer" | "pantry"
      useBy?: string
      barcode?: string
      brand?: string
      mergeInto?: {
        itemId: string
        name: string
      }
    }[]
    scanId: string
    status: "done" | "failed" | "running"
  }
}
GET/v1/me/food/pantry/scans/:scanId

A pantry photo being read: running, then done with the items to check (placed, with estimated use-bys and what each would add to), or failed.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:read (when actor.type === "user")
Get an API key

Path parameters

  • scanId

    A pantry photo being read (fsc_…).

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:read on a key made by a person.
curl 'https://api.cactive.com.au/v1/me/food/pantry/scans/{scanId}' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  scan: {
    createdAt: number
    error?: string
    items?: {
      name: string
      ingredientId?: string
      quantity?: number
      unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
      place: "fridge" | "freezer" | "pantry"
      useBy?: string
      barcode?: string
      brand?: string
      mergeInto?: {
        itemId: string
        name: string
      }
    }[]
    scanId: string
    status: "done" | "failed" | "running"
  }
}
PATCH/v1/me/food/pantry/:itemId

Changes something in the pantry (useBy: null clears its date).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Path parameters

  • itemId

    Drive file (fil_…) or folder (fld_…) id, or a drive id for its top folder; under me/food a shopping list item (fli_…) or something in the pantry (fpn_…).

Request body

  • nameany JSON
  • quantitynumber

    0–100000.

  • unitany
  • place"pantry" | "fridge" | "freezer"
  • useBystringor null

    Matches ^\d{4}-\d{2}-\d{2}$.

Also checked: Unknown fields are rejected.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X PATCH 'https://api.cactive.com.au/v1/me/food/pantry/{itemId}' \
  -H "Authorization: Bearer $CACTIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "name": {},
    "quantity": 1,
    "unit": "example"
  }'
Send it from this page with your session or a key.

Response 200

{
  item: {
    itemId: string
    name: string
    ingredientId?: string
    quantity?: number
    unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
    place: "fridge" | "freezer" | "pantry"
    useBy?: string
    addedBy: string
    addedAt: number
    source?: "photo" | "manual" | "receipt" | "leftovers" | "barcode"
    barcode?: string
    leftover?: {
      recipeId: string
      title: string
      portions: number
      cookedOn: string
    }
  }
}
POST/v1/me/food/pantry/remove

Takes things out of the pantry (used up).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Request body

  • itemIdsstring[]required

    1–500 items. Each 1–60 characters.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X POST 'https://api.cactive.com.au/v1/me/food/pantry/remove' \
  -H "Authorization: Bearer $CACTIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "itemIds": [
      "example"
    ]
  }'
Send it from this page with your session or a key.

Response 200

{
  removed: number
}
GET/v1/me/food/cookable

"What can I cook?": the person's and household's recipes by how much the pantry covers, with what's missing.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:read (when actor.type === "user")
Get an API key

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:read on a key made by a person.
curl 'https://api.cactive.com.au/v1/me/food/cookable' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  recipes: {
    recipe: {
      createdAt: number
      updatedAt: number
      title: string
      tags: string[]
      ownerId: string
      shared?: boolean
      favourite?: boolean
      recipeId: string
      servings: number
      totalMinutes?: number
      cuisines: string[]
      courses: string[]
      rating?: number
      household: boolean
      cookedCount: number
      lastCookedAt?: number
      diets: string[]
      allergens: string[]
      kcalPerServing?: number
      ingredientIds: string[]
      amounts?: {
        [key: string]: {
          g?: number
          ml?: number
          each?: number
          minor?: true
        }
      }
      measuredLines?: number
      image?: {
        imageId: string
        versionId?: string
        mime?: string
        width?: number
        height?: number
        alt?: string
        url: string
        thumbUrl: string
      }
    }
    have: number
    need: number
    missing: string[]
    expiring: string[]
  }[]
}
GET/v1/me/food/receipts

The household's grocery receipts, newest purchase first (status: new, added or dismissed).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:read (when actor.type === "user")
Get an API key

Query parameters

  • status"new" | "added" | "dismissed"

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:read on a key made by a person.
curl 'https://api.cactive.com.au/v1/me/food/receipts' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  receipts: {
    receiptId: string
    store: string
    storeName: string
    purchasedOn: string
    total?: number
    lines: {
      id: string
      text: string
      name: string
      ingredientId?: string
      quantity?: number
      unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
      price?: number
      detail?: string
      food: boolean
      place?: "fridge" | "freezer" | "pantry"
      useBy?: string
    }[]
    status: "added" | "dismissed" | "new"
    via: "upload" | "mail" | "forward"
    read: "model" | "rules"
    userId?: string
    createdAt: number
    addedAt?: number
    addedBy?: string
    added?: number
  }[]
}
GET/v1/me/food/receipts/settings

Receipts settings: the household's forwarding address (when made), whether receipts go straight in, Gmail's last confirmation, and the person's Cactive Mail link.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:read (when actor.type === "user")
Get an API key

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:read on a key made by a person.
curl 'https://api.cactive.com.au/v1/me/food/receipts/settings' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  stores: {
    sender?: string
    id: string
    name: string
  }[]
  mail?: {
    orgId: string
    mailboxId: string
    address: string
    since: number
    backfilledAt?: number
  }
  confirmation?: {
    code?: string
    link?: string
    at: number
  }
  autoAdd: boolean
  forwarding?: string
}
PATCH/v1/me/food/receipts/settings

Whether the household's new receipts go straight into the pantry (autoAdd) or wait for review.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Request body

  • autoAddbooleanrequired

Also checked: Unknown fields are rejected.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X PATCH 'https://api.cactive.com.au/v1/me/food/receipts/settings' \
  -H "Authorization: Bearer $CACTIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "autoAdd": true
  }'
Send it from this page with your session or a key.

Response 200

{
  home: {
    receipts: {
      autoAdd: boolean
      token?: string
      confirmation?: {
        code?: string
        link?: string
        at: number
      }
    }
    homeId: string
    name: string
    members: {
      userId: string
      name?: string
      role: "owner" | "member"
      joinedAt: number
    }[]
    createdAt: number
  }
}
POST/v1/me/food/receipts/forwarding

Makes the household's private forwarding address (or a new one with rotate: the old one stops working).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Request body

  • rotateboolean

Also checked: Unknown fields are rejected.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X POST 'https://api.cactive.com.au/v1/me/food/receipts/forwarding' \
  -H "Authorization: Bearer $CACTIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "rotate": true
  }'
Send it from this page with your session or a key.

Response 200

{
  address: string
}
PUT/v1/me/food/receipts/mail

Turns on grocery receipts from one of the person's Cactive Mail mailboxes (they must be a member): Food then reads only mail from the stores' e-receipt senders there.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Request body

  • orgIdstringrequired

    1–64 characters.

  • mailboxIdstringrequired

    1–64 characters.

Also checked: Unknown fields are rejected.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
  • 403You can't read mail in that organization.
  • 404Mailbox not found
curl -X PUT 'https://api.cactive.com.au/v1/me/food/receipts/mail' \
  -H "Authorization: Bearer $CACTIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "orgId": "<orgId>",
    "mailboxId": "<mailboxId>"
  }'
Send it from this page with your session or a key.

Response 200

{
  settings: {
    measure: "metric" | "original" | "imperial"
    spoons: "au" | "us"
    defaultServings: number
    diets: string[]
    avoidAllergens: string[]
    weeknightMinutes?: number
    weatherSuggestions: boolean
    healthLogging: boolean
    calendar?: {
      orgId: string
      calendarId: string
    }
    weekStartsOn: number
    receiptMail?: {
      orgId: string
      mailboxId: string
      address: string
      since: number
      backfilledAt?: number
    }
    useSoonAlerts: boolean
    voiceControl: boolean
    weeklyBudget?: number
    timeZone?: string
  }
}
DELETE/v1/me/food/receipts/mail

Stops reading grocery receipts from the person's Cactive Mail; receipts already read stay.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X DELETE 'https://api.cactive.com.au/v1/me/food/receipts/mail' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  settings: {
    measure: "metric" | "original" | "imperial"
    spoons: "au" | "us"
    defaultServings: number
    diets: string[]
    avoidAllergens: string[]
    weeknightMinutes?: number
    weatherSuggestions: boolean
    healthLogging: boolean
    calendar?: {
      orgId: string
      calendarId: string
    }
    weekStartsOn: number
    receiptMail?: {
      orgId: string
      mailboxId: string
      address: string
      since: number
      backfilledAt?: number
    }
    useSoonAlerts: boolean
    voiceControl: boolean
    weeklyBudget?: number
    timeZone?: string
  }
}
POST/v1/me/food/receipts/mail/backfill

"Check the last 30 days" (once): the linked mailbox's mail from the stores' e-receipt senders, read for receipts.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Errors

  • 400Turn on receipts from Cactive Mail first.
  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X POST 'https://api.cactive.com.au/v1/me/food/receipts/mail/backfill' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 202

{
  queued: number
}
GET/v1/me/food/receipts/:receiptId

One receipt (decrypted): the store, the day, the total and each line with its price, amount, place and estimated use-by.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:read (when actor.type === "user")
Get an API key

Path parameters

  • receiptId

    A grocery receipt (frc_…).

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:read on a key made by a person.
curl 'https://api.cactive.com.au/v1/me/food/receipts/{receiptId}' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  receipt: {
    receiptId: string
    store: string
    storeName: string
    purchasedOn: string
    total?: number
    lines: {
      id: string
      text: string
      name: string
      ingredientId?: string
      quantity?: number
      unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
      price?: number
      detail?: string
      food: boolean
      place?: "fridge" | "freezer" | "pantry"
      useBy?: string
    }[]
    status: "added" | "dismissed" | "new"
    via: "upload" | "mail" | "forward"
    read: "model" | "rules"
    userId?: string
    createdAt: number
    addedAt?: number
    addedBy?: string
    added?: number
  }
}
POST/v1/me/food/receipts/:receiptId/add

Puts a receipt into the pantry: its food lines, or the lines as ticked and changed (merged into what's there).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Path parameters

  • receiptId

    A grocery receipt (frc_…).

Request body

  • linesobject[]

    Up to 500 items.

  • lines[].idstringrequired

    Up to 40 characters.

  • lines[].includeboolean
  • lines[].namestring

    1–200 characters. Trimmed.

  • lines[].quantitynumberor null

    0–100000.

  • lines[].unitany JSONor null
  • lines[].place"pantry" | "fridge" | "freezer"
  • lines[].useBystringor null

    Matches ^\d{4}-\d{2}-\d{2}$.

  • lines[].mergeboolean

Also checked: Unknown fields are rejected.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X POST 'https://api.cactive.com.au/v1/me/food/receipts/{receiptId}/add' \
  -H "Authorization: Bearer $CACTIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "lines": [
      {
        "id": "<id>"
      }
    ]
  }'
Send it from this page with your session or a key.

Response 200

{
  receipt: {
    receiptId: string
    store: string
    storeName: string
    purchasedOn: string
    total?: number
    lines: {
      id: string
      text: string
      name: string
      ingredientId?: string
      quantity?: number
      unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
      price?: number
      detail?: string
      food: boolean
      place?: "fridge" | "freezer" | "pantry"
      useBy?: string
    }[]
    status: "added" | "dismissed" | "new"
    via: "upload" | "mail" | "forward"
    read: "model" | "rules"
    userId?: string
    createdAt: number
    addedAt?: number
    addedBy?: string
    added?: number
  }
}
POST/v1/me/food/receipts/:receiptId/dismiss

Leaves a receipt out of the pantry (it still counts in spending).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Path parameters

  • receiptId

    A grocery receipt (frc_…).

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X POST 'https://api.cactive.com.au/v1/me/food/receipts/{receiptId}/dismiss' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  receipt: {
    status: "dismissed"
    receiptId: string
    store: string
    storeName: string
    purchasedOn: string
    total?: number
    lines: {
      id: string
      text: string
      name: string
      ingredientId?: string
      quantity?: number
      unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
      price?: number
      detail?: string
      food: boolean
      place?: "fridge" | "freezer" | "pantry"
      useBy?: string
    }[]
    via: "upload" | "mail" | "forward"
    read: "model" | "rules"
    userId?: string
    createdAt: number
    addedAt?: number
    addedBy?: string
    added?: number
  }
}
DELETE/v1/me/food/receipts

Deletes the household's receipts and prices (and the key they're sealed with).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X DELETE 'https://api.cactive.com.au/v1/me/food/receipts' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  removed: number
}
GET/v1/me/food/spending

Grocery spending by month from the household's receipts (months: 1 to 24, 6 by default).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:read (when actor.type === "user")
Get an API key

Query parameters

  • monthsinteger

    1–24. Coerced from a string.

  • todaystring

    Matches ^\d{4}-\d{2}-\d{2}$.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:read on a key made by a person.
curl 'https://api.cactive.com.au/v1/me/food/spending' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  months: {
    month: string
    total: number
    receipts: number
    stores: {
      name: string
      total: number
    }[]
  }[]
}
POST/v1/me/food/delete-all

Deletes all the person's Food data (call again while done is false): see docs/food/README.md → Privacy.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X POST 'https://api.cactive.com.au/v1/me/food/delete-all' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  done: boolean
  remaining: number
}
GET/v1/me/food/suggestions

Ideas from the person's recipes with why (ratings, history, the season, the pantry, the weather when turned on), within their diets and allergens.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:read (when actor.type === "user")
Get an API key

Query parameters

  • maxMinutesstring

    Default "".

  • coursestring

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:read on a key made by a person.
curl 'https://api.cactive.com.au/v1/me/food/suggestions' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  suggestions: {
    score: number
    reasons: string[]
    recipe: {
      createdAt: number
      updatedAt: number
      title: string
      tags: string[]
      ownerId: string
      shared?: boolean
      favourite?: boolean
      recipeId: string
      servings: number
      totalMinutes?: number
      cuisines: string[]
      courses: string[]
      rating?: number
      household: boolean
      cookedCount: number
      lastCookedAt?: number
      diets: string[]
      allergens: string[]
      kcalPerServing?: number
      ingredientIds: string[]
      amounts?: {
        [key: string]: {
          g?: number
          ml?: number
          each?: number
          minor?: true
        }
      }
      measuredLines?: number
      image?: {
        imageId: string
        versionId?: string
        mime?: string
        width?: number
        height?: number
        alt?: string
        url: string
        thumbUrl: string
      }
    }
  }[]
}
GET/v1/me/food/substitutes

Substitutes for an ingredient from Food's kitchen notes, with amounts (none on file: an empty list and a note).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:read (when actor.type === "user")
Get an API key

Query parameters

  • ingredientstringrequired

    1–100 characters.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:read on a key made by a person.
curl 'https://api.cactive.com.au/v1/me/food/substitutes?ingredient=example' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  note?: string
  ingredient: string
  substitutes: {
    use: string
    note?: string
  }[]
}
GET/v1/me/food/widget

The phone's widgets: tonight's dinner and the first list's next items.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:read (when actor.type === "user")
Get an API key

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:read on a key made by a person.
curl 'https://api.cactive.com.au/v1/me/food/widget' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  today: string
  tonight: null | {
    title: string
    meal: string
    recipeId?: string
    minutes?: number
    imageUrl?: string
  }
  list: null | {
    listId: string
    name: string
    remaining: number
    items: {
      itemId: string
      name: string
      amount: string
      aisle: "none" | "other" | "household" | "meat" | "dairy" | "breakfast" | "baking" | "produce" | "bakery" | "seafood" | "deli" | "chilled" | "pasta" | "canned" | "condiments" | "oils" | "spices" | "nuts" | "spreads" | "frozen" | "drinks"
    }[]
  }
}
POST/v1/me/food/imports/url

A web page's recipe as a draft to check (schema.org data, else its lists); a page without either is read by the model as an import.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Request body

  • urlstringrequired

    4–2,000 characters.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X POST 'https://api.cactive.com.au/v1/me/food/imports/url' \
  -H "Authorization: Bearer $CACTIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "https://example.com"
  }'
Send it from this page with your session or a key.

Response 200

{
  draft?: {
    title: string
    description?: string
    source?: {
      kind: "text" | "photo" | "web" | "manual" | "melt" | "paprika" | "mela" | "crouton" | "copymethat" | "assistant" | "copy"
      url?: string
      name?: string
      author?: string
    }
    tags?: string[]
    steps?: {
      id: string
      section?: string
      text: string
      timers?: {
        seconds: number
        label?: string
      }[]
    }[]
    favourite?: boolean
    publicToken?: string
    servings?: number
    yieldLabel?: string
    prepMinutes?: number
    cookMinutes?: number
    totalMinutes?: number
    ingredients?: {
      id: string
      section?: string
      quantity?: number
      quantityMax?: number
      unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
      item: string
      note?: string
      ingredientId?: string
      optional?: boolean
    }[]
    cuisines?: string[]
    courses?: string[]
    claimedDiets?: string[]
    difficulty?: "medium" | "easy" | "hard"
    spoons?: "au" | "us"
    notes?: string
    rating?: number
    household?: boolean
    lastCookedAt?: number
    imageUrls?: string[]
  }
  from?: string
  import?: {
    importId: string
    kind: "text" | "photo" | "web" | "manual" | "melt" | "paprika" | "mela" | "crouton" | "copymethat" | "assistant" | "copy"
    status: "done" | "failed" | "running"
    label: string
    recipeIds: string[]
    skipped: number
    error?: string
    createdAt: number
    updatedAt: number
  }
}
POST/v1/me/food/imports/text

Recipes in pasted text as drafts to check (several when separated by a line of dashes).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Request body

  • textstringrequired

    1–100,000 characters.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X POST 'https://api.cactive.com.au/v1/me/food/imports/text' \
  -H "Authorization: Bearer $CACTIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "text": "example"
  }'
Send it from this page with your session or a key.

Response 200

{
  drafts: {
    title: string
    description?: string
    source?: {
      kind: "text" | "photo" | "web" | "manual" | "melt" | "paprika" | "mela" | "crouton" | "copymethat" | "assistant" | "copy"
      url?: string
      name?: string
      author?: string
    }
    tags?: string[]
    steps?: {
      id: string
      section?: string
      text: string
      timers?: {
        seconds: number
        label?: string
      }[]
    }[]
    favourite?: boolean
    publicToken?: string
    servings?: number
    yieldLabel?: string
    prepMinutes?: number
    cookMinutes?: number
    totalMinutes?: number
    ingredients?: {
      id: string
      section?: string
      quantity?: number
      quantityMax?: number
      unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
      item: string
      note?: string
      ingredientId?: string
      optional?: boolean
    }[]
    cuisines?: string[]
    courses?: string[]
    claimedDiets?: string[]
    difficulty?: "medium" | "easy" | "hard"
    spoons?: "au" | "us"
    notes?: string
    rating?: number
    household?: boolean
    lastCookedAt?: number
    imageUrls?: string[]
    images?: string[]
  }[]
}
POST/v1/me/food/imports/photos

Photos or screenshots of one recipe (base64, up to four), read by the model; poll the import for its draft.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Request body (up to 10,240 KB)

  • photosstring[]required

    1–4 items. Each 10–12,000,000 characters.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
  • 413That's too large. Send pictures of at most 8 MB, four at a time.
curl -X POST 'https://api.cactive.com.au/v1/me/food/imports/photos' \
  -H "Authorization: Bearer $CACTIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "photos": [
      "example"
    ]
  }'
Send it from this page with your session or a key.

Response 202

{
  import: {
    importId: string
    kind: "text" | "photo" | "web" | "manual" | "melt" | "paprika" | "mela" | "crouton" | "copymethat" | "assistant" | "copy"
    status: "done" | "failed" | "running"
    label: string
    recipeIds: string[]
    skipped: number
    error?: string
    createdAt: number
    updatedAt: number
    draft?: {
      title: string
      description?: string
      source?: {
        kind: "text" | "photo" | "web" | "manual" | "melt" | "paprika" | "mela" | "crouton" | "copymethat" | "assistant" | "copy"
        url?: string
        name?: string
        author?: string
      }
      tags?: string[]
      steps?: {
        id: string
        section?: string
        text: string
        timers?: {
          seconds: number
          label?: string
        }[]
      }[]
      favourite?: boolean
      publicToken?: string
      servings?: number
      yieldLabel?: string
      prepMinutes?: number
      cookMinutes?: number
      totalMinutes?: number
      ingredients?: {
        id: string
        section?: string
        quantity?: number
        quantityMax?: number
        unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
        item: string
        note?: string
        ingredientId?: string
        optional?: boolean
      }[]
      cuisines?: string[]
      courses?: string[]
      claimedDiets?: string[]
      difficulty?: "medium" | "easy" | "hard"
      spoons?: "au" | "us"
      notes?: string
      rating?: number
      household?: boolean
      lastCookedAt?: number
      imageUrls?: string[]
    }
  }
}
POST/v1/me/food/imports/files

Starts importing another app's export: a link to PUT the file to, then complete.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Request body

  • namestringrequired

    1–200 characters.

  • sizeintegerrequired

    ≥ 1.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X POST 'https://api.cactive.com.au/v1/me/food/imports/files' \
  -H "Authorization: Bearer $CACTIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Example",
    "size": 1
  }'
Send it from this page with your session or a key.

Response 201

{
  importId: string
  uploadUrl: string
  contentType: string
}
POST/v1/me/food/imports/:importId/complete

The file has been sent: the worker reads it and saves its recipes (and Melt's cookbooks as collections).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:write (when actor.type === "user")
Get an API key

Path parameters

  • importId

    Takeout import id (imp_…); under me/food a Food import (fim_…); under vehicles an import of a car's history (vim_…), as the imports list gives it.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:write on a key made by a person.
curl -X POST 'https://api.cactive.com.au/v1/me/food/imports/{importId}/complete' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 202

{
  import: {
    importId: string
    kind: "text" | "photo" | "web" | "manual" | "melt" | "paprika" | "mela" | "crouton" | "copymethat" | "assistant" | "copy"
    status: "done" | "failed" | "running"
    label: string
    recipeIds: string[]
    skipped: number
    error?: string
    createdAt: number
    updatedAt: number
    draft?: {
      title: string
      description?: string
      source?: {
        kind: "text" | "photo" | "web" | "manual" | "melt" | "paprika" | "mela" | "crouton" | "copymethat" | "assistant" | "copy"
        url?: string
        name?: string
        author?: string
      }
      tags?: string[]
      steps?: {
        id: string
        section?: string
        text: string
        timers?: {
          seconds: number
          label?: string
        }[]
      }[]
      favourite?: boolean
      publicToken?: string
      servings?: number
      yieldLabel?: string
      prepMinutes?: number
      cookMinutes?: number
      totalMinutes?: number
      ingredients?: {
        id: string
        section?: string
        quantity?: number
        quantityMax?: number
        unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
        item: string
        note?: string
        ingredientId?: string
        optional?: boolean
      }[]
      cuisines?: string[]
      courses?: string[]
      claimedDiets?: string[]
      difficulty?: "medium" | "easy" | "hard"
      spoons?: "au" | "us"
      notes?: string
      rating?: number
      household?: boolean
      lastCookedAt?: number
      imageUrls?: string[]
    }
  }
}
GET/v1/me/food/imports

Your imports from the last two weeks: what they read, saved and skipped, or why they failed.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:read (when actor.type === "user")
Get an API key

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:read on a key made by a person.
curl 'https://api.cactive.com.au/v1/me/food/imports' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  imports: {
    importId: string
    kind: "text" | "photo" | "web" | "manual" | "melt" | "paprika" | "mela" | "crouton" | "copymethat" | "assistant" | "copy"
    status: "done" | "failed" | "running"
    label: string
    recipeIds: string[]
    skipped: number
    error?: string
    createdAt: number
    updatedAt: number
    draft?: {
      title: string
      description?: string
      source?: {
        kind: "text" | "photo" | "web" | "manual" | "melt" | "paprika" | "mela" | "crouton" | "copymethat" | "assistant" | "copy"
        url?: string
        name?: string
        author?: string
      }
      tags?: string[]
      steps?: {
        id: string
        section?: string
        text: string
        timers?: object[]
      }[]
      favourite?: boolean
      publicToken?: string
      servings?: number
      yieldLabel?: string
      prepMinutes?: number
      cookMinutes?: number
      totalMinutes?: number
      ingredients?: {
        id: string
        section?: string
        quantity?: number
        quantityMax?: number
        unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
        item: string
        note?: string
        ingredientId?: string
        optional?: boolean
      }[]
      cuisines?: string[]
      courses?: string[]
      claimedDiets?: string[]
      difficulty?: "medium" | "easy" | "hard"
      spoons?: "au" | "us"
      notes?: string
      rating?: number
      household?: boolean
      lastCookedAt?: number
      imageUrls?: string[]
    }
  }[]
}
GET/v1/me/food/imports/:importId

One import: its status and, for one recipe read from photos or a page, the draft to check.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:read (when actor.type === "user")
Get an API key

Path parameters

  • importId

    Takeout import id (imp_…); under me/food a Food import (fim_…); under vehicles an import of a car's history (vim_…), as the imports list gives it.

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:read on a key made by a person.
curl 'https://api.cactive.com.au/v1/me/food/imports/{importId}' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  import: {
    importId: string
    kind: "text" | "photo" | "web" | "manual" | "melt" | "paprika" | "mela" | "crouton" | "copymethat" | "assistant" | "copy"
    status: "done" | "failed" | "running"
    label: string
    recipeIds: string[]
    skipped: number
    error?: string
    createdAt: number
    updatedAt: number
    draft?: {
      title: string
      description?: string
      source?: {
        kind: "text" | "photo" | "web" | "manual" | "melt" | "paprika" | "mela" | "crouton" | "copymethat" | "assistant" | "copy"
        url?: string
        name?: string
        author?: string
      }
      tags?: string[]
      steps?: {
        id: string
        section?: string
        text: string
        timers?: {
          seconds: number
          label?: string
        }[]
      }[]
      favourite?: boolean
      publicToken?: string
      servings?: number
      yieldLabel?: string
      prepMinutes?: number
      cookMinutes?: number
      totalMinutes?: number
      ingredients?: {
        id: string
        section?: string
        quantity?: number
        quantityMax?: number
        unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
        item: string
        note?: string
        ingredientId?: string
        optional?: boolean
      }[]
      cuisines?: string[]
      courses?: string[]
      claimedDiets?: string[]
      difficulty?: "medium" | "easy" | "hard"
      spoons?: "au" | "us"
      notes?: string
      rating?: number
      household?: boolean
      lastCookedAt?: number
      imageUrls?: string[]
    }
  }
}
GET/v1/me/food/export

Everything of yours in Food as a file Food imports again (format: cactive-food): recipes, collections, settings and history. Pictures are links valid for an hour.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:read (when actor.type === "user")
Get an API key

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:read on a key made by a person.
curl 'https://api.cactive.com.au/v1/me/food/export' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  format: string
  version: number
  exportedAt: string
  settings: {
    measure: "metric" | "original" | "imperial"
    spoons: "au" | "us"
    defaultServings: number
    diets: string[]
    avoidAllergens: string[]
    weeknightMinutes?: number
    weatherSuggestions: boolean
    healthLogging: boolean
    calendar?: {
      orgId: string
      calendarId: string
    }
    weekStartsOn: number
    receiptMail?: {
      orgId: string
      mailboxId: string
      address: string
      since: number
      backfilledAt?: number
    }
    useSoonAlerts: boolean
    voiceControl: boolean
    weeklyBudget?: number
    timeZone?: string
  }
  recipes: {
    imageUrls?: string[]
    recipeId: string
    ownerId: string
    title: string
    description?: string
    servings: number
    yieldLabel?: string
    prepMinutes?: number
    cookMinutes?: number
    totalMinutes?: number
    ingredients: {
      id: string
      section?: string
      quantity?: number
      quantityMax?: number
      unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
      item: string
      note?: string
      ingredientId?: string
      optional?: boolean
    }[]
    steps: {
      id: string
      section?: string
      text: string
      timers?: {
        seconds: number
        label?: string
      }[]
    }[]
    cuisines: string[]
    courses: string[]
    claimedDiets: string[]
    tags: string[]
    difficulty?: "medium" | "easy" | "hard"
    spoons: "au" | "us"
    source?: {
      kind: "text" | "photo" | "web" | "manual" | "melt" | "paprika" | "mela" | "crouton" | "copymethat" | "assistant" | "copy"
      url?: string
      name?: string
      author?: string
    }
    notes?: string
    rating?: number
    favourite?: boolean
    household: boolean
    cookedCount: number
    lastCookedAt?: number
    createdAt: number
    updatedAt: number
    version: number
    pictures?: string[]
  }[]
  collections: {
    name: string
    description?: string
    recipeIds: string[]
  }[]
  household: {
    name: string
    members: {
      name?: string
      role: "owner" | "member"
      joinedAt: string
    }[]
    plan: {
      [key: string]: unknown
    }[]
    lists: {
      listId: string
      homeId: string
      name: string
      items: {
        itemId: string
        name: string
        quantity?: number
        unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
        amount?: string
        aisle: "none" | "other" | "household" | "meat" | "dairy" | "breakfast" | "baking" | "produce" | "bakery" | "seafood" | "deli" | "chilled" | "pasta" | "canned" | "condiments" | "oils" | "spices" | "nuts" | "spreads" | "frozen" | "drinks"
        ingredientId?: string
        note?: string
        checked: boolean
        forRecipes?: string[]
        addedBy: string
        addedAt: number
        checkedBy?: string
      }[]
      createdAt: number
      updatedAt: number
      version: number
    }[]
    pantry: {
      itemId: string
      name: string
      ingredientId?: string
      quantity?: number
      unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
      place: "fridge" | "freezer" | "pantry"
      useBy?: string
      addedBy: string
      addedAt: number
      source?: "photo" | "manual" | "receipt" | "leftovers" | "barcode"
      barcode?: string
      leftover?: {
        recipeId: string
        title: string
        portions: number
        cookedOn: string
      }
    }[]
    receipts: {
      receiptId: string
      store: string
      storeName: string
      purchasedOn: string
      total?: number
      lines: {
        id: string
        text: string
        name: string
        ingredientId?: string
        quantity?: number
        unit?: "slice" | "head" | "g" | "kg" | "mg" | "oz" | "lb" | "ml" | "l" | "tsp" | "tbsp" | "cup" | "floz" | "pint" | "quart" | "pinch" | "dash" | "piece" | "clove" | "can" | "jar" | "bunch" | "handful" | "sprig" | "sheet" | "packet" | "stick" | "fillet" | "rasher" | "leaf" | "stalk"
        price?: number
        detail?: string
        food: boolean
        place?: "fridge" | "freezer" | "pantry"
        useBy?: string
      }[]
      status: "added" | "dismissed" | "new"
      via: "upload" | "mail" | "forward"
      read: "model" | "rules"
      userId?: string
      createdAt: number
      addedAt?: number
      addedBy?: string
      added?: number
    }[]
    prices: {
      key: string
      ingredientId?: string
      name: string
      paid: number
      perG?: number
      perMl?: number
      perEach?: number
      store: string
      storeName: string
      day: string
    }[]
  }
  cooked: {
    note?: string
    rating?: number
    recipeId: string
    title: string
    at: string
  }[]
}
GET/v1/me/food/exports

Your ZIP exports from the last day, newest first, each with its status and, once ready, a download link per ZIP (an hour long).

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:read (when actor.type === "user")
Get an API key

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:read on a key made by a person.
curl 'https://api.cactive.com.au/v1/me/food/exports' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  exports: {
    exportId: string
    status: "queued" | "ready" | "failed"
    files: number
    bytes: number
    createdAt: number
    expiresAt: number
    archives: {
      archiveId: string
      name: string
      status: string
      files: number
      bytes: number
      url?: string
    }[]
  }[]
}
POST/v1/me/food/exports

Starts a ZIP export: the export's JSON (food-export.json) with your recipes' pictures beside it, made in the background and kept a day. Check it until ready; a few a day.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:read (when actor.type === "user")
Get an API key

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:read on a key made by a person.
curl -X POST 'https://api.cactive.com.au/v1/me/food/exports' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 202

{
  export: {
    exportId: string
    status: "queued" | "ready" | "failed"
    files: number
    bytes: number
    createdAt: number
    expiresAt: number
    archives: {
      archiveId: string
      name: string
      status: string
      files: number
      bytes: number
      url?: string
    }[]
  }
}
GET/v1/me/food/exports/:exportId

One ZIP export: queued, ready (each ZIP's url) or failed.

Auth
A person's token or an API key, as Authorization: Bearer.
Scope
food:read (when actor.type === "user")
Get an API key

Path parameters

  • exportId

    An export's id (pex_… for Photos, oex_… for an organization).

Errors

  • 403Food isn't available to the phone assistant.
  • 403Food is reachable from the Food and phone apps.
  • 403Food needs food:read on a key made by a person.
curl 'https://api.cactive.com.au/v1/me/food/exports/{exportId}' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  export: {
    exportId: string
    status: "queued" | "ready" | "failed"
    files: number
    bytes: number
    createdAt: number
    expiresAt: number
    archives: {
      archiveId: string
      name: string
      status: string
      files: number
      bytes: number
      url?: string
    }[]
  }
}