API Documentation
Complete reference for the RecipeBook API
Introduction
Welcome to the RecipeBook API! Our REST API provides a simple, yet powerful interface to access and manage recipes, categories, tags, and more.
The API is built with Laravel and follows REST conventions. All responses are in JSON format.
Base URL: https://recipe.rmartorell.nl/api/v1
Authentication
Currently, the RecipeBook API does not require authentication. All endpoints are publicly accessible.
Note: Authentication may be added in future versions for write operations.
Response Format
All API responses follow a consistent JSON format:
{
"data": [
{ /* resource object */ }
],
"links": {
"first": "...",
"last": "..."
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 1,
"per_page": 15,
"to": 15,
"total": 15
}
}
Filtering
The API supports filtering using query parameters. Use the following format to filter results:
GET https://recipe.rmartorell.nl/api/v1/endpoint?filter[field][operator]=value
Supported Operators:
| Operator | Description | Example |
|---|---|---|
eq |
Equal to | ?filter[id][eq]=1 |
like |
Contains (case-insensitive) | ?filter[name][like]=pizza |
lt |
Less than | ?filter[id][lt]=10 |
gt |
Greater than | ?filter[id][gt]=1 |
Endpoints
Recipes
Manage and retrieve recipes
List Recipes
GETGET https://recipe.rmartorell.nl/api/v1/recipes
Retrieve a paginated list of all recipes with their categories, tags, and descriptions.
Query Parameters
filter[name][like]- Filter by recipe name
Example Response
https://recipe.rmartorell.nl/api/v1/recipes?filter[name][like]=pasta
Get Single Recipe
GETGET https://recipe.rmartorell.nl/api/v1/recipes/{id}
Retrieve a single recipe by its ID with all associated data.
Path Parameters
id- Recipe ID (integer)
Example
https://recipe.rmartorell.nl/api/v1/recipes/1
Categories
Manage recipe categories
List Categories
GETGET https://recipe.rmartorell.nl/api/v1/categories
Retrieve a paginated list of all categories with recipe counts.
Query Parameters
filter[name][like]- Filter by category name
Example
https://recipe.rmartorell.nl/api/v1/categories?filter[name][like]=dessert
Get Single Category
GETGET https://recipe.rmartorell.nl/api/v1/categories/{id}
Retrieve a single category by its ID with recipe count.
Path Parameters
id- Category ID (integer)
Example
https://recipe.rmartorell.nl/api/v1/categories/1
Tags
Manage recipe tags
List Tags
GETGET https://recipe.rmartorell.nl/api/v1/tags
Retrieve a paginated list of all tags with recipe counts.
Query Parameters
filter[name][like]- Filter by tag name
Example
https://recipe.rmartorell.nl/api/v1/tags?filter[name][like]=vegetarian
Get Single Tag
GETGET https://recipe.rmartorell.nl/api/v1/tags/{id}
Retrieve a single tag by its ID with recipe count.
Path Parameters
id- Tag ID (integer)
Example
https://recipe.rmartorell.nl/api/v1/tags/1
Response Objects
Recipe Object
{
"id": 1,
"name": "Spaghetti Carbonara",
"category": {
"id": 1,
"name": "Italian",
"recipes_count": 12
},
"tags": [
{
"id": 1,
"name": "Quick",
"recipes_count": 45
}
],
"descriptions": [
{
"id": 1,
"description": "Traditional Italian pasta...",
"language": {
"id": 1,
"code": "en",
"name": "English"
}
}
]
}
Category Object
{
"id": 1,
"name": "Italian",
"recipes_count": 12
}
Tag Object
{
"id": 1,
"name": "Quick",
"recipes_count": 45
}
Filter Examples
Filter Recipes by Name (Partial Match)
Search for recipes containing a specific word or phrase using the like operator for case-insensitive matching.
Request URL:
GET https://recipe.rmartorell.nl/api/v1/recipes?filter[name][like]=pasta
Returns all recipes with names containing "pasta" (case-insensitive)
Response Example:
{
"data": [
{
"id": 1,
"name": "Spaghetti Carbonara",
"category": {
"id": 2,
"name": "Italian",
"recipes_count": 12
},
"tags": [
{
"id": 1,
"name": "Quick",
"recipes_count": 45
}
],
"descriptions": [
{
"id": 1,
"description": "<p>Traditional Italian pasta...</p>",
"language": {
"id": 1,
"code": "en",
"name": "English"
}
}
],
"ingredients": {
"en": {
"language": {
"code": "en",
"name": "English",
"id": 1
},
"items": [
{
"id": 1,
"name": "Spaghetti",
"quantity": "400",
"unit": "gram",
"order": 0
},
{
"id": 2,
"name": "Eggs",
"quantity": "4",
"unit": "pieces",
"order": 1
}
]
},
"nl": {
"language": {
"code": "nl",
"name": "Dutch",
"id": 2
},
"items": [
{
"id": 1,
"name": "Spaghetti",
"quantity": "400",
"unit": "gram",
"order": 0
},
{
"id": 2,
"name": "Eieren",
"quantity": "4",
"unit": "stuks",
"order": 1
}
]
},
"original": [
{
"id": 1,
"name": "Spaghetti",
"quantity": "400",
"unit": "gram",
"order": 0
},
{
"id": 2,
"name": "Eggs",
"quantity": "4",
"unit": "pieces",
"order": 1
}
]
}
}
]
}
Tip: The like operator searches anywhere within the field. For example:
- •
?filter[name][like]=pastamatches "Spaghetti Carbonara", "Pasta Primavera", "Fresh Pasta" - •
?filter[name][like]=cakematches "Chocolate Cake", "Cheesecake", "Birthday Cake"
Filter Recipes by Exact Name
Search for recipes with an exact name match using the eq operator (case-sensitive).
Request URL:
GET https://recipe.rmartorell.nl/api/v1/recipes?filter[name][eq]=Spaghetti Carbonara
Returns only recipes with the exact name "Spaghetti Carbonara"
Response Example:
{
"data": [
{
"id": 1,
"name": "Spaghetti Carbonara",
"category": {
"id": 2,
"name": "Italian",
"recipes_count": 12
},
"tags": [
{
"id": 1,
"name": "Quick",
"recipes_count": 45
}
],
"descriptions": [
{
"id": 1,
"description": "<p>Traditional Italian pasta...</p>",
"language": {
"id": 1,
"code": "en",
"name": "English"
}
}
],
"ingredients": {
"en": {
"language": {
"code": "en",
"name": "English",
"id": 1
},
"items": [
{
"id": 1,
"name": "Spaghetti",
"quantity": "400",
"unit": "gram",
"order": 0
}
]
},
"original": [
{
"id": 1,
"name": "Spaghetti",
"quantity": "400",
"unit": "gram",
"order": 0
}
]
}
}
]
}
Note: The eq operator requires an exact match and is case-sensitive. For partial matches or case-insensitive searches, use like instead.
Combining Multiple Filters
You can combine multiple filters to narrow down results. Currently, the API supports filtering by name.
Request URL:
GET https://recipe.rmartorell.nl/api/v1/recipes?filter[name][like]=pizza&filter[id][gt]=5
Returns recipes with names containing "pizza" AND id greater than 5
Available Filter Combinations:
| Operator | SQL Equivalent | Use Case |
|---|---|---|
eq |
= |
Exact match |
like |
LIKE |
Partial/substring match (case-insensitive) |
lt |
< |
Less than (for numeric fields) |
gt |
> |
Greater than (for numeric fields) |
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}`);
});
});
Code Examples
JavaScript / Fetch API
// Get all recipes
fetch('https://recipe.rmartorell.nl/api/v1/recipes')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
// Search for recipes by name (partial match, case-insensitive)
fetch('https://recipe.rmartorell.nl/api/v1/recipes?filter[name][like]=pasta')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
// Search for exact recipe name
fetch('https://recipe.rmartorell.nl/api/v1/recipes?filter[name][eq]=Spaghetti Carbonara')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
// Get a specific recipe by ID
fetch('https://recipe.rmartorell.nl/api/v1/recipes/1')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
PHP / Laravel (HTTP Client)
use Illuminate\Support\Facades\Http;
// Get all recipes
$response = Http::get('https://recipe.rmartorell.nl/api/v1/recipes');
$recipes = $response->json();
// Search for recipes by name (partial match, case-insensitive)
$response = Http::get('https://recipe.rmartorell.nl/api/v1/recipes', [
'filter' => ['name' => ['like' => 'pasta']]
]);
$recipes = $response->json();
// Search for exact recipe name
$response = Http::get('https://recipe.rmartorell.nl/api/v1/recipes', [
'filter' => ['name' => ['eq' => 'Spaghetti Carbonara']]
]);
$recipes = $response->json();
// Get a specific recipe by ID
$response = Http::get('https://recipe.rmartorell.nl/api/v1/recipes/1');
$recipe = $response->json();
cURL
# Get all recipes
curl "https://recipe.rmartorell.nl/api/v1/recipes"
# Search for recipes by name (partial match, case-insensitive)
curl "https://recipe.rmartorell.nl/api/v1/recipes?filter[name][like]=pasta"
# Search for exact recipe name
curl "https://recipe.rmartorell.nl/api/v1/recipes?filter[name][eq]=Spaghetti Carbonara"
# Get a specific recipe by ID
curl "https://recipe.rmartorell.nl/api/v1/recipes/1"
Error Handling
The API returns standard HTTP status codes to indicate the result of an API request. In case of errors, a JSON response will be provided with error details and the appropriate HTTP status code.
400 Bad Request / 422 Unprocessable Entity
Invalid filter operators or malformed filter parameters
{
"error": "Validation Failed",
"message": "The provided data failed validation.",
"errors": {
"filter.name.invalidop": [
"Invalid operator 'invalidop' for field 'name'. Allowed operators: like, eq"
]
},
"status": 422
}
Test URLs:
https://recipe.rmartorell.nl/api/v1/recipes?filter[name][invalidop]=test
https://recipe.rmartorell.nl/api/v1/recipes?filter[id][badop]=5
404 Not Found - Resource
The requested resource does not exist
{
"error": "Not Found",
"message": "The requested resource was not found.",
"status": 404
}
Test URLs:
https://recipe.rmartorell.nl/api/v1/recipes/99999
https://recipe.rmartorell.nl/api/v1/categories/99999
https://recipe.rmartorell.nl/api/v1/tags/99999
404 Not Found - Endpoint
The requested API endpoint does not exist
{
"error": "Route Not Found",
"message": "The requested API endpoint does not exist. Please check the API documentation at /api-docs",
"status": 404
}
Test URLs:
https://recipe.rmartorell.nl/api/v1/invalid
https://recipe.rmartorell.nl/api/v1/recipes/invalid/endpoint
https://recipe.rmartorell.nl/api/v1/nonexistent
422 Unprocessable Entity
The request was well-formed but contains validation errors
{
"error": "Validation Failed",
"message": "The provided data failed validation.",
"errors": {
"name": [
"The name field is required."
]
},
"status": 422
}
Note:
This error occurs during POST/PUT requests with invalid data validation (read-only API currently)
500 Internal Server Error
An unexpected server error occurred
{
"error": "Internal Server Error",
"message": "An unexpected error occurred. Please try again later.",
"status": 500
}
Note:
This error occurs when the server encounters an unexpected condition. Contact support if you encounter this error.
HTTP Status Codes Reference
| Code | Meaning | Description |
|---|---|---|
200 |
OK | Request succeeded |
400 |
Bad Request | Invalid parameters or request format |
404 |
Not Found | Resource or endpoint not found |
422 |
Unprocessable Entity | Validation errors in request data |
500 |
Internal Server Error | Server-side error occurred |
Need Help?
If you have any questions or need assistance with the API, feel free to reach out to our support team.
Back to Home