NutriPatrol API

NutriPatrol is the Open Food Facts moderation backend — it takes tickets and flags on products and images and exposes them to the moderation front end. Serves its own OpenAPI 3.1 document from the live host.

Operations 11

GET / Main Page #
GET /robots.txt Robots Txt #
GET /api/v1/flags Get Flags #
POST /api/v1/flags Create Flag #
GET /api/v1/flags/{flag_id} Get Flag #
GET /api/v1/tickets Get Tickets #
GET /api/v1/tickets/{ticket_id} Get Ticket #
POST /api/v1/flags/batch Get Flags By Ticket Batch #
PUT /api/v1/tickets/{ticket_id}/status Update Ticket Status #
GET /api/v1/stats Get Stats #
GET /api/v1/status Status #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/open-food-facts-nutripatrol"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

open-food-facts-nutripatrol-openapi.json Raw ↑
{"openapi":"3.1.0","info":{"title":"nutripatrol","description":"\nThe nutripatrol API is used to report and manage issues with products and images on [Open Food Facts](https://world.openfoodfacts.org/), Open Prices, Open Pet Food Facts, Open Beauty Facts.\nWe call a report a \"**flag**\" and a report will be associated with a \"**ticket**\" if it does not exist for this product or image. Otherwise it will be associated with the existing ticket.\n\n## Flags\n\nA flag containes the following main fields:\n- `barcode`: Barcode of the product, if the flag is about a product or a product image. In case of a search issue, this field is null.\n\n- `type`: Type of the issue. It can be `product`, `image` or `search`.\n- `url`: URL of the product or of the flagged image.\n- `user_id`: Open Food Facts User ID of the flagger.\n- `source`: Source of the flag. It can be a user from the mobile app, the web or a flag generated automatically by robotoff.\n- `confidence`: Confidence score of the model that generated the flag, this field should only be provided by Robotoff.\n- `image_id`: ID of the flagged image, if the ticket type is `image`.\n- `flavor`: Flavor (project) associated with the ticket.\n- `reason`: Reason for flagging provided by the user. For images, it can be `inappropriate`, `human`, `beauty` or `other`\n\n`image_to_delete_spam` or `image_to_delete_face`. For products it can be `product_to_delete`. The field is optional.\n- `comment`: Comment provided by the user during flagging. This is a free text field.\n\n## Tickets\nAutomatically created when a flag is created and no ticket exists for the product or image.\n\nA ticket containes the following main fields:\n- `barcode`: Barcode of the product, if the ticket is about a product or a product image. In case of a search issue, this field is null.\n\n- `type`: Type of the issue. It can be `product`, `image` or `search`.\n- `url`: URL of the product or of the flagged image.\n- `status`: Status of the ticket. It can be `open` or `closed`.\n- `image_id`: ID of the flagged image, if the ticket type is `image`.\n- `flavor`: Flavor (project) associated with the ticket.\n\n\n","contact":{"name":"The Open Food Facts team","url":"https://world.openfoodfacts.org/","email":"contact@openfoodfacts.org"},"license":{"name":" AGPL-3.0","url":"https://www.gnu.org/licenses/agpl-3.0.en.html"},"version":"0.1.0"},"paths":{"/":{"get":{"summary":"Main Page","operationId":"main_page__get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/robots.txt":{"get":{"summary":"Robots Txt","operationId":"robots_txt_robots_txt_get","responses":{"200":{"description":"Successful Response","content":{"text/plain":{"schema":{"type":"string"}}}}}}},"/api/v1/flags":{"get":{"summary":"Get Flags","description":"Get all flags.\n\nThis function is used to get all flags.","operationId":"get_flags_api_v1_flags_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetFlagsResponse"}}}}}},"post":{"summary":"Create Flag","description":"Create a flag for a product.\n\nThis function is used to create a flag for a product or an image.\nA flag is a request for a product or an image to be reviewed.\nA flag is associated with a ticket.\nA ticket is created if it does not exist for this product or image.\nA ticket can be associated with multiple flags.","operationId":"create_flag_api_v1_flags_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlagCreate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Flag"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/flags/{flag_id}":{"get":{"summary":"Get Flag","description":"Get a flag by ID.\n\nThis function is used to get a flag by its ID.","operationId":"get_flag_api_v1_flags__flag_id__get","parameters":[{"name":"flag_id","in":"path","required":true,"schema":{"type":"integer","title":"Flag Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Flag"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tickets":{"get":{"summary":"Get Tickets","description":"Get all tickets.\n\nThis function is used to get all tickets with status open.","operationId":"get_tickets_api_v1_tickets_get","parameters":[{"name":"barcode","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Barcode"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/TicketStatus"},{"type":"null"}],"title":"Status"}},{"name":"type_","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/IssueType"},{"type":"null"}],"title":"Type "}},{"name":"reason","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/ReasonType"}},{"type":"null"}],"title":"Reason"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","default":10,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetTicketsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tickets/{ticket_id}":{"get":{"summary":"Get Ticket","description":"Get a ticket by ID.\n\nThis function is used to get a ticket by its ID.","operationId":"get_ticket_api_v1_tickets__ticket_id__get","parameters":[{"name":"ticket_id","in":"path","required":true,"schema":{"type":"integer","title":"Ticket Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/flags/batch":{"post":{"summary":"Get Flags By Ticket Batch","description":"Get all flags for tickets by IDs.\n\nThis function is used to get all flags for tickets by there IDs.","operationId":"get_flags_by_ticket_batch_api_v1_flags_batch_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlagsByTicketIdRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tickets/{ticket_id}/status":{"put":{"summary":"Update Ticket Status","description":"Update the status of a ticket by ID.\n\nThis function is used to update the status of a ticket by its ID.","operationId":"update_ticket_status_api_v1_tickets__ticket_id__status_put","parameters":[{"name":"ticket_id","in":"path","required":true,"schema":{"type":"integer","title":"Ticket Id"}},{"name":"status","in":"query","required":true,"schema":{"$ref":"#/components/schemas/TicketStatus"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ticket"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/stats":{"get":{"summary":"Get Stats","description":"Get number of tickets by status for the last n days.\n\nArgs:\n    n_days (int): The number of days from which to fetch ticket data.\n    Default is 31 days.","operationId":"get_stats_api_v1_stats_get","parameters":[{"name":"n_days","in":"query","required":false,"schema":{"type":"integer","default":31,"title":"N Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/status":{"get":{"summary":"Status","description":"Health check endpoint.","operationId":"status_api_v1_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatusResponse"}}}}}}}},"components":{"schemas":{"Flag":{"properties":{"barcode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Barcode","description":"Barcode of the product, if the flag is about a product or a product image. In case of a search issue, this field is null."},"type":{"$ref":"#/components/schemas/IssueType","description":"Type of the issue"},"url":{"type":"string","title":"Url","description":"URL of the product or of the flagged image"},"user_id":{"type":"string","title":"User Id","description":"Open Food Facts User ID of the flagger"},"source":{"$ref":"#/components/schemas/SourceType","description":"Source of the flag. It can be a user from the mobile app, the web or a flag generated automatically by robotoff."},"confidence":{"anyOf":[{"type":"number","maximum":1.0,"minimum":0.0},{"type":"null"}],"title":"Confidence","description":"Confidence score of the model that generated the flag, this field should only be provided by Robotoff."},"image_id":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"title":"Image Id","description":"ID of the flagged image","examples":["1","front_fr"]},"flavor":{"$ref":"#/components/schemas/Flavor","description":"Flavor (project) associated with the ticket"},"reason":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"title":"Reason","description":"Reason for flagging provided by the user. The field is optional."},"comment":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Comment","description":"Comment provided by the user during flagging. This is a free text field."},"created_at":{"type":"string","format":"date-time","title":"Created At","description":"Creation datetime of the flag"},"id":{"type":"integer","title":"Id","description":"ID of the flag"},"ticket_id":{"type":"integer","title":"Ticket Id","description":"ID of the ticket associated with the flag"},"device_id":{"type":"string","title":"Device Id","description":"Device ID of the flagger"}},"type":"object","required":["type","url","user_id","source","flavor","id","ticket_id","device_id"],"title":"Flag"},"FlagCreate":{"properties":{"barcode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Barcode","description":"Barcode of the product, if the flag is about a product or a product image. In case of a search issue, this field is null."},"type":{"$ref":"#/components/schemas/IssueType","description":"Type of the issue"},"url":{"type":"string","title":"Url","description":"URL of the product or of the flagged image"},"user_id":{"type":"string","title":"User Id","description":"Open Food Facts User ID of the flagger"},"source":{"$ref":"#/components/schemas/SourceType","description":"Source of the flag. It can be a user from the mobile app, the web or a flag generated automatically by robotoff."},"confidence":{"anyOf":[{"type":"number","maximum":1.0,"minimum":0.0},{"type":"null"}],"title":"Confidence","description":"Confidence score of the model that generated the flag, this field should only be provided by Robotoff."},"image_id":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"title":"Image Id","description":"ID of the flagged image","examples":["1","front_fr"]},"flavor":{"$ref":"#/components/schemas/Flavor","description":"Flavor (project) associated with the ticket"},"reason":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"title":"Reason","description":"Reason for flagging provided by the user. The field is optional."},"comment":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Comment","description":"Comment provided by the user during flagging. This is a free text field."},"created_at":{"type":"string","format":"date-time","title":"Created At","description":"Creation datetime of the flag"}},"type":"object","required":["type","url","user_id","source","flavor"],"title":"FlagCreate"},"FlagsByTicketIdRequest":{"properties":{"ticket_ids":{"items":{"type":"integer"},"type":"array","title":"Ticket Ids"}},"type":"object","required":["ticket_ids"],"title":"FlagsByTicketIdRequest"},"Flavor":{"type":"string","enum":["off","obf","opff","opf","off-pro"],"title":"Flavor","description":"Flavor is used to refer to a specific Open*Facts project:\n\n- Open Food Facts\n- Open Beauty Facts\n- Open Pet Food Facts\n- Open Product Facts\n- Open Food Facts (Pro plateform)"},"GetFlagsResponse":{"properties":{"flags":{"items":{"$ref":"#/components/schemas/Flag"},"type":"array","title":"Flags"}},"type":"object","required":["flags"],"title":"GetFlagsResponse"},"GetTicketsResponse":{"properties":{"tickets":{"items":{"$ref":"#/components/schemas/Ticket"},"type":"array","title":"Tickets"},"max_page":{"type":"integer","title":"Max Page"}},"type":"object","required":["tickets","max_page"],"title":"GetTicketsResponse","description":"Response model for get_tickets endpoint."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"IssueType":{"type":"string","enum":["product","image","search"],"title":"IssueType","description":"Type of the flag/ticket."},"ReasonType":{"type":"string","enum":["inappropriate","human","beauty","other"],"title":"ReasonType","description":"Type of the reason for flagging."},"SourceType":{"type":"string","enum":["mobile","web","robotoff"],"title":"SourceType"},"StatsResponse":{"properties":{"total_tickets":{"type":"integer","title":"Total Tickets","description":"Total number of tickets in the database"},"tickets_by_status":{"additionalProperties":true,"type":"object","title":"Tickets By Status","description":"A dictionary with ticket status as keys and the count of tickets as values"},"tickets_by_flavor":{"additionalProperties":true,"type":"object","title":"Tickets By Flavor","description":"A dictionary with ticket flavor as keys and the count of tickets as values"},"tickets_by_type":{"additionalProperties":true,"type":"object","title":"Tickets By Type","description":"A dictionary with ticket type as keys and the count of tickets as values"},"n_days":{"type":"integer","title":"N Days","description":"The number of days for which the data is fetched"},"start_date":{"type":"string","title":"Start Date","description":"The start date of the data range in ISO format"},"end_date":{"type":"string","title":"End Date","description":"The end date of the data range in ISO format"}},"type":"object","required":["total_tickets","tickets_by_status","tickets_by_flavor","tickets_by_type","n_days","start_date","end_date"],"title":"StatsResponse","description":"Response model for get_stats endpoint."},"StatusResponse":{"properties":{"status":{"type":"string","title":"Status","description":"Health status of the API"}},"type":"object","required":["status"],"title":"StatusResponse"},"Ticket":{"properties":{"barcode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Barcode","description":"Barcode of the product, if the ticket is about a product or a product image. In case of a search issue, this field is null."},"type":{"$ref":"#/components/schemas/IssueType","description":"Type of the issue"},"url":{"type":"string","title":"Url","description":"URL of the product or of the flagged image"},"status":{"$ref":"#/components/schemas/TicketStatus","description":"Status of the ticket","default":"open"},"image_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Id","description":"ID of the flagged image, if the ticket type is `image`","examples":["1","front_fr"]},"flavor":{"$ref":"#/components/schemas/Flavor","description":"Flavor (project) associated with the ticket"},"created_at":{"type":"string","format":"date-time","title":"Created At","description":"Creation datetime of the ticket"},"id":{"type":"integer","title":"Id","description":"ID of the ticket"}},"type":"object","required":["type","url","flavor","id"],"title":"Ticket"},"TicketStatus":{"type":"string","enum":["open","closed"],"title":"TicketStatus"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}}}