API Documentation

Auto-generated from the current API configuration - always up to date with what is actually routed.

Base URL: https://recipe.rmartorell.nl

Authentication

Every endpoint below is public - no token required for any of them.

Response format

A list endpoint (index) returns its items wrapped in "data":

{
  "data": [
    { /* ... */ }
  ]
}

A single-item endpoint (show, store, update) returns the same shape with one object instead of an array:

{
  "data": { /* ... */ }
}

Filter operators

Usage: ?filter[field][operator]=value

OperatorMeaningSQL equivalent
eqExact match=
likePartial match, case-insensitiveLIKE
ltLess than<
gtGreater than>

Endpoints

v1 https://recipe.rmartorell.nl/api/v1

recipes

Public - no token required

index

GET
GET https://recipe.rmartorell.nl/api/v1/recipes

show

GET
GET https://recipe.rmartorell.nl/api/v1/recipes/{id}

Custom output shape - see the app's own documentation.

Filterable fields
name - like
GET https://recipe.rmartorell.nl/api/v1/recipes?filter[name][like]=value

categories

Public - no token required

index

GET
GET https://recipe.rmartorell.nl/api/v1/categories

show

GET
GET https://recipe.rmartorell.nl/api/v1/categories/{id}
Example response

No records yet - values below are placeholders derived from the database schema, not real data.

{
    "data": {
        "id": 1,
        "name": "string",
        "recipes_count": 0
    }
}
Output fields
idname recipes_count
Filterable fields
name - like
GET https://recipe.rmartorell.nl/api/v1/categories?filter[name][like]=value

tags

Public - no token required

index

GET
GET https://recipe.rmartorell.nl/api/v1/tags

show

GET
GET https://recipe.rmartorell.nl/api/v1/tags/{id}
Example response

No records yet - values below are placeholders derived from the database schema, not real data.

{
    "data": {
        "id": 1,
        "name": "string",
        "recipes_count": 0
    }
}
Output fields
idname recipes_count
Filterable fields
name - like
GET https://recipe.rmartorell.nl/api/v1/tags?filter[name][like]=value

Code examples

JavaScript / Fetch API

fetch('https://recipe.rmartorell.nl/api/v1/recipes')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));

PHP / Laravel (HTTP Client)

use Illuminate\Support\Facades\Http;

$response = Http::get('https://recipe.rmartorell.nl/api/v1/recipes');
$data = $response->json();

cURL

curl "https://recipe.rmartorell.nl/api/v1/recipes"

Error handling

Every error response is JSON with the same shape - an "error" label, a human-readable "message", and the HTTP status code repeated in the body.

422 - Validation failed

The request body, or an unsupported filter operator, failed validation - "errors" lists each problem field.

{
  "error": "Validation Failed",
  "message": "The provided data failed validation.",
  "errors": { "filter...": ["Invalid operator..."] },
  "status": 422
}
Try it: https://recipe.rmartorell.nl/api/v1/recipes?filter[name][invalidop]=x

404 - Resource not found

The requested record does not exist.

{
  "error": "Not Found",
  "message": "The requested resource was not found.",
  "status": 404
}
Try it: https://recipe.rmartorell.nl/api/v1/recipes/999999

404 - Endpoint not found

No route matches the requested path.

{
  "error": "Route Not Found",
  "message": "The requested API endpoint does not exist.",
  "status": 404
}

500 - Internal server error

An unexpected error occurred; the message is deliberately generic in production.

{
  "error": "Internal Server Error",
  "message": "An unexpected error occurred. Please try again later.",
  "status": 500
}

Ingredients Structure

Recipe ingredients are returned grouped by language for easy multilingual support. Each recipe includes ingredients in all available translated languages, plus the original ingredients.

Structure Format

The ingredients field is an object with language codes as keys:

"ingredients": {
  "en": {
    "language": {
      "code": "en",
      "name": "English",
      "id": 1
    },
    "items": [
      {
        "id": 1,
        "name": "Flour",
        "quantity": "200",
        "unit": "gram",
        "order": 0
      }
    ]
  },
  "nl": {
    "language": {
      "code": "nl",
      "name": "Dutch",
      "id": 2
    },
    "items": [
      {
        "id": 1,
        "name": "Bloem",
        "quantity": "200",
        "unit": "gram",
        "order": 0
      }
    ]
  },
  "original": [
    {
      "id": 1,
      "name": "Flour",
      "quantity": "200",
      "unit": "gram",
      "order": 0
    }
  ]
}

Key Components

Language Keys (e.g., "en", "nl", "az")
Each language code contains translated ingredients for that language, sorted alphabetically by language code.

"original"
Contains the base ingredients in the recipe's default language. Always appears last.

language
Metadata about the language (code, name, id) for each language group.

items
Array of translated ingredients, each with id, name, quantity, unit, and order.

Usage Examples

JavaScript - Get Specific Language

// Get Dutch ingredients
const dutchIngredients = recipe.ingredients.nl?.items || [];

// Get English ingredients
const englishIngredients = recipe.ingredients.en?.items || [];

// Fallback to original if translation doesn't exist
const ingredients = recipe.ingredients.nl?.items || recipe.ingredients.original;

JavaScript - Loop All Languages

// Get all available language codes
const languages = Object.keys(recipe.ingredients).filter(k => k !== 'original');

// Loop through each language
languages.forEach(langCode => {
  const group = recipe.ingredients[langCode];
  console.log(`${group.language.name}:`);
  group.items.forEach(ing => {
    console.log(`- ${ing.quantity} ${ing.unit} ${ing.name}`);
  });
});