generated: '2026-08-27' method: derived source: >- openapi/tandoor-api-openapi.yml, https://docs.tandoor.dev/features/import_export/, https://docs.tandoor.dev/features/authentication/, https://tandoor.dev/privacy/, https://github.com/TandoorRecipes/recipes/blob/develop/recipes/settings.py summary: >- Tandoor's cross-cutting conformance is thin and honest: a valid OpenAPI 3.0.3 contract, page-number pagination, and a genuine domain-standard signature in schema.org/Recipe — the vocabulary its whole import pipeline is built on. It does NOT implement RFC 9457 problem details, does not expose OAuth 2.0 or OIDC authorization endpoints (despite carrying django-oauth-toolkit as an authentication class), and publishes no compliance certifications. standards: - id: openapi conforms: true version: 3.0.3 evidence: >- A drf-spectacular-generated OpenAPI 3.0.3 document is served unauthenticated at https://app.tandoor.dev/openapi/ (and at /openapi/ on every self-hosted instance) — 244 paths, 462 operations, 244 component schemas, HTTP 200, content-type application/vnd.oai.openapi. - id: schema-org-recipe conforms: true evidence: >- Tandoor's URL importer parses schema.org/Recipe (JSON-LD and microdata) from third-party recipe sites, and its own recipe model is shaped around the same vocabulary — name, description, image, keywords, recipeIngredient, recipeInstructions, cookTime/prepTime, recipeYield, nutrition. The documentation links https://schema.org/Recipe directly from the import/export page. This is the domain standard for the recipe market and Tandoor speaks it natively. docs: https://docs.tandoor.dev/features/import_export/ - id: ical conforms: true evidence: >- GET /api/meal-plan/ical/ (operationId apiMealPlanIcalRetrieve) returns text/calendar — the only non-JSON response media type in the whole contract. Meal plans are exportable to any RFC 5545 calendar client. - id: pagination conforms: true style: page-number evidence: >- 113 list operations take `page` and `page_size` query parameters and return the DRF PageNumberPagination envelope {count, next, previous, results} — 44 Paginated*List component schemas in the contract. - id: rfc9457 conforms: false evidence: >- No operation declares an application/problem+json response. The contract declares only 200, 201 and 204 — zero 4xx/5xx responses across all 462 operations. Errors observed live use the django-rest-framework field-error envelope, e.g. POST /api-token-auth/ with an empty body returns HTTP 400 {"username":["This field is required."],"password":["This field is required."]}. - id: idempotency conforms: false evidence: >- No Idempotency-Key header is defined anywhere in the contract and none is documented. PUT and PATCH are naturally idempotent by HTTP semantics; POST creates are not protected. - id: oauth2 conforms: false evidence: >- django-oauth-toolkit is installed and OAuth2Authentication is a DEFAULT_AUTHENTICATION_CLASS, and settings.py defines four scopes (read, write, bookmarklet, mealplan) — but oauth2_provider.urls is not included in the URL configuration, so no authorize or token endpoint is served. Probes of https://app.tandoor.dev/o/authorize/ and /o/token/ both return 302 to the login page (the Django catch-all), not an OAuth endpoint. The scopes exist in code and are not reachable over HTTP. - id: oidc conforms: false evidence: >- OpenID Connect is supported INBOUND only — django-allauth can be configured with an openid_connect provider so operators can sign users in from their own IdP. Tandoor is not an OIDC provider; /.well-known/openid-configuration returns 302 (login redirect) on app.tandoor.dev and 404 on tandoor.dev. - id: asyncapi conforms: false evidence: >- No event, streaming or webhook surface. The "Connectors" feature (beta) pushes OUTBOUND to Home Assistant todo lists using credentials the operator stores in Tandoor; it is not a webhook subscription API for consumers and has no event catalogue. N/A rather than a failure. docs: https://docs.tandoor.dev/features/connectors/ compliance: certifications: [] trust_center: false claims: - claim: GDPR compliant, made in Germany source: https://tandoor.dev/ evidence: >- Marketing claim on the tandoor.dev home page ("GDPR Compliant - Made in Germany"), backed by a German Impressum naming the sole trader (Benedikt Sienz, Falkensee) and a privacy policy at https://tandoor.dev/privacy/. This is a self-declared regulatory posture, not an audited certification — no SOC 2, ISO 27001, PCI DSS or HIPAA attestation is published anywhere. - claim: No tracking or analytics source: https://tandoor.dev/ note: >- No `Compliance` pointer is emitted in apis.yml. A GDPR self-declaration on a marketing page is not a published compliance programme, and emitting the pointer would credit this provider with a certification posture it does not claim to have.