{"openapi":"3.1.0","info":{"title":"Hermetics API","version":"1.0.0","description":"EU data protection law and the record of processing activities (GDPR art. 30): the official texts with their status, the obligations of a company, and the records, analyses, requests and breaches of your Hermetics account. Information, not legal advice: without a designated DPO, the final decision is yours.","contact":{"email":"contact@hermetics.fr","url":"https://hermetics.fr/mcp"}},"externalDocs":{"description":"Assistants and API","url":"https://hermetics.fr/mcp#api"},"servers":[{"url":"https://hermetics.fr"}],"tags":[{"name":"Law","description":"Official texts and obligations (read only)."},{"name":"Records","description":"Your register, analyses, requests and breaches (writes to your account)."},{"name":"MCP","description":"The Model Context Protocol endpoint."}],"paths":{"/api/v1/tools/search_law":{"post":{"operationId":"search_law","summary":"Search EU data protection law","description":"Searches the official texts on data protection (GDPR, ePrivacy, AI Act, EDPB guidance, CJEU case law, and the national law, authority guidance and decisions held for each country) and returns the most relevant passages verbatim, each with its current status (in force, applicable from a date, amended) and its official link.","tags":["Law"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"question":{"type":"string","minLength":3,"maxLength":2000,"description":"The legal question, in any language (French gives the best results today). Names and personal data are not needed."},"country":{"type":"string","enum":["AT","BE","BG","HR","CY","CZ","DK","EE","FI","FR","DE","GR","HU","IE","IT","LV","LT","LU","MT","NL","PL","PT","RO","SK","SI","ES","SE","IS","LI","NO"],"description":"ISO code of an EU or EEA country (e.g. FR, DE, ES) to add its national law and authority guidance to the EU texts; omit for EU texts only."}},"required":["question"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool result: `result` holds the structured data, `text` the same answer as plain text.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}}}},"401":{"description":"Missing or invalid key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown tool.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid arguments, a limit of the plan reached, or the tool could not complete the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests from this address; retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Temporarily unavailable; retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/tools/gdpr_obligations":{"post":{"operationId":"gdpr_obligations","summary":"GDPR obligations of a company","description":"Lists the GDPR obligations of a company established in an EU or EEA country from a few facts (size, website and cookies, e-mail marketing, sensitive data, video surveillance, AI...). Deterministic rules: each obligation comes with its legal basis and a suggested search_law query for the official text. A fact left out is treated as unknown, except processors, which are assumed.","tags":["Law"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"country":{"type":"string","enum":["AT","BE","BG","HR","CY","CZ","DK","EE","FI","FR","DE","GR","HU","IE","IT","LV","LT","LU","MT","NL","PL","PT","RO","SK","SI","ES","SE","IS","LI","NO"],"description":"Country where the company is established (ISO code of an EU or EEA country, e.g. FR, DE, ES, IT)."},"employees":{"type":"integer","minimum":0,"maximum":1000000,"description":"Number of employees (0 if none)."},"public_sector":{"type":"boolean","description":"True if the organisation is a public authority or public body."},"website":{"type":"boolean","description":"True if the company has a website or app."},"non_essential_cookies":{"type":"boolean","description":"True if the website or app uses non-essential cookies or trackers (analytics, advertising, social media pixels)."},"email_marketing":{"type":"boolean","description":"True if the company sends marketing e-mails or SMS to individuals."},"processors":{"type":"boolean","description":"True if providers process personal data on its behalf (hosting, SaaS, payroll, CRM). Assumed true if omitted."},"transfers_outside_eea":{"type":"boolean","description":"True if personal data is sent to providers or entities outside the EEA (e.g. US SaaS)."},"special_category_data":{"type":"boolean","description":"True if it processes special category data (health, biometrics, genetic data, religion, union membership, sex life or orientation, ethnic origin, political opinions)."},"large_scale":{"type":"boolean","description":"True if the processing concerns a large number of people (large scale)."},"systematic_monitoring":{"type":"boolean","description":"True if it systematically monitors people (online behaviour tracking, geolocation, profiling for advertising, CCTV of public areas)."},"evaluation_or_scoring":{"type":"boolean","description":"True if it evaluates or scores people (credit scoring, profiling, performance rating)."},"automated_decisions":{"type":"boolean","description":"True if it takes automated decisions with legal or similarly significant effects on people."},"vulnerable_people":{"type":"boolean","description":"True if it processes data of vulnerable people (children, patients, elderly people)."},"cctv":{"type":"boolean","description":"True if it uses video surveillance (CCTV)."},"ai":{"type":"boolean","description":"True if it develops or uses AI systems that interact with or make decisions about people."}},"required":["country"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool result: `result` holds the structured data, `text` the same answer as plain text.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}}}},"401":{"description":"Missing or invalid key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown tool.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid arguments, a limit of the plan reached, or the tool could not complete the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests from this address; retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Temporarily unavailable; retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/tools/save_processing_record":{"post":{"operationId":"save_processing_record","summary":"Save a record of processing activity","description":"Saves one entry of the record of processing activities (GDPR art. 30(1)) in the Hermetics account linked to the connection: new records get a code and every change is kept as a new version, in the account's own register on the Hermetics platform (the free account has no DPO: the user checks the records). When the account belongs to a Hermetics client organization, records go to that organization's register on the Hermetics platform (codes AT-001...), pending its DPO's review; a change to a record the DPO has validated is sent to the DPO as a proposal. Returns the code, the version and the points a DPO would review in the entry; when an existing record is updated, also what changed from the previous version and what the change requires (information notice, proof of consent, processor contract, transfer safeguard, DPIA review). The free account stores 35 records; the paid plans have no record limit.","tags":["Records"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":3,"maxLength":150,"description":"Short name of the processing activity (e.g. \"Payroll\", \"Newsletter\")."},"purpose":{"type":"string","minLength":10,"maxLength":1000,"description":"Purpose of the processing (art. 30(1)(b))."},"legal_basis":{"type":"string","enum":["consent","contract","legal_obligation","vital_interests","public_task","legitimate_interests"],"description":"Legal basis under art. 6(1)."},"legal_basis_details":{"type":"string","maxLength":1000,"description":"Details of the legal basis: the legal obligation, the contract, or the legitimate interest pursued."},"data_subjects":{"type":"array","items":{"type":"string","minLength":1,"maxLength":200},"minItems":1,"maxItems":30,"description":"Categories of data subjects (art. 30(1)(c)), e.g. \"employees\", \"customers\"."},"data_categories":{"type":"array","items":{"type":"string","minLength":1,"maxLength":200},"minItems":1,"maxItems":30,"description":"Categories of personal data (art. 30(1)(c)), e.g. \"identity\", \"bank details\"."},"special_category_data":{"type":"boolean","description":"True if special category data (art. 9) are processed."},"art9_exception":{"type":"string","maxLength":500,"description":"The art. 9(2) exception relied on, if special category data are processed."},"recipients":{"type":"array","items":{"type":"string","minLength":1,"maxLength":200},"minItems":1,"maxItems":30,"description":"Categories of recipients, internal and external (art. 30(1)(d))."},"processors":{"type":"array","items":{"type":"string","minLength":1,"maxLength":200},"maxItems":30,"description":"Processors acting on behalf of the company (art. 28)."},"transfers_outside_eea":{"type":"object","properties":{"countries":{"type":"array","items":{"type":"string","minLength":2,"maxLength":100},"minItems":1,"maxItems":30},"safeguard":{"type":"string","maxLength":300,"description":"Adequacy decision, standard contractual clauses, etc. (art. 44 to 49)."}},"required":["countries"],"additionalProperties":false,"description":"Transfers to third countries (art. 30(1)(e)); omit if none."},"retention":{"type":"string","minLength":3,"maxLength":500,"description":"Retention period or the criteria used to determine it (art. 30(1)(f))."},"security_measures":{"type":"array","items":{"type":"string","minLength":1,"maxLength":200},"maxItems":30,"description":"General description of technical and organisational security measures (art. 30(1)(g))."},"record_id":{"type":"string","description":"Code of an existing record (e.g. RT-001, or AT-001 in an organization register) to save a new version of it; omit to create a new record."}},"required":["name","purpose","legal_basis","data_subjects","data_categories","recipients","retention"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool result: `result` holds the structured data, `text` the same answer as plain text.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}}}},"401":{"description":"Missing or invalid key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown tool.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid arguments, a limit of the plan reached, or the tool could not complete the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests from this address; retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Temporarily unavailable; retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/tools/list_processing_records":{"post":{"operationId":"list_processing_records","summary":"List the records of processing activities","description":"Lists the records of processing activities (GDPR art. 30(1)) saved in the Hermetics account linked to the connection, in their latest version, with their full content. For an account of a Hermetics client organization, lists the organization's whole register on the Hermetics platform, whatever the origin of each record, with its status.","tags":["Law"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool result: `result` holds the structured data, `text` the same answer as plain text.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}}}},"401":{"description":"Missing or invalid key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown tool.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid arguments, a limit of the plan reached, or the tool could not complete the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests from this address; retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Temporarily unavailable; retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/tools/pending_reviews":{"post":{"operationId":"pending_reviews","summary":"Records to review after a change in the law","description":"Lists the records of processing activities that a new rule (law, guidance, decision) may affect, with the rule, its source and the reason; saving a new version of a record closes its reviews. Reviews are part of the paid plans.","tags":["Law"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool result: `result` holds the structured data, `text` the same answer as plain text.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}}}},"401":{"description":"Missing or invalid key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown tool.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid arguments, a limit of the plan reached, or the tool could not complete the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests from this address; retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Temporarily unavailable; retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/tools/prepare_analysis":{"post":{"operationId":"prepare_analysis","summary":"Prepare a compliance analysis","description":"Prepares, in the Hermetics space of the organization, the analysis of a record of the register with the same engines as the Hermetics platform: legal basis, DPIA, legitimate interests assessment, transfer impact assessment, information notice (art. 13 and 14), the privacy policy of the whole register, or the art. 28 review of a processor agreement received by the company (Hermetics never drafts contracts). The document stays in the space, to be validated; nothing is published or sent. Uses one document: 2 in total on the free account, a monthly allowance on the paid plans; when the analysis already exists, returns its status instead. Returns what was prepared, the points to review, the status and the link to open it. Prepared from the facts given; the decision is the user's, or the designated DPO validates it when the organization has one.","tags":["Records"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"record_id":{"type":"string","description":"Code of the record in the register (e.g. AT-001); required for every type except privacy_policy."},"type":{"type":"string","enum":["legal_basis","dpia","lia","tia","information_notice","privacy_policy","processor_agreement_review"],"description":"legal_basis (art. 6), dpia (art. 35), lia (legitimate interests assessment), tia (transfer impact assessment, art. 44 to 49), information_notice (art. 13 and 14), privacy_policy (the whole register), processor_agreement_review (art. 28 review of a processor agreement received by the company)."},"notes":{"type":"string","maxLength":2000,"description":"Facts or context from the user for the preparation; no personal data needed."},"processor_name":{"type":"string","minLength":2,"maxLength":200,"description":"Name of the processor whose agreement is reviewed (processor_agreement_review only)."},"agreement_text":{"type":"string","minLength":200,"maxLength":60000,"description":"Full text of the processor agreement received by the company (processor_agreement_review only)."}},"required":["type"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool result: `result` holds the structured data, `text` the same answer as plain text.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}}}},"401":{"description":"Missing or invalid key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown tool.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid arguments, a limit of the plan reached, or the tool could not complete the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests from this address; retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Temporarily unavailable; retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/tools/record_request":{"post":{"operationId":"record_request","summary":"Record a data subject request","description":"Records a data subject request (access, rectification, erasure, restriction, portability, objection) in the Hermetics space of the organization, with its code and the legal deadline (one month from receipt, art. 12(3), extendable). Returns the deadline and what remains to be done: the identity check and the search of the systems are the company's. Nothing is sent to the requester. The free account tracks 10 requests a year; the paid plans have no limit. Prepared from the facts given; the decision is the user's, or the designated DPO validates it when the organization has one.","tags":["Records"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"right":{"type":"string","enum":["access","rectification","erasure","restriction","portability","objection"],"description":"The right exercised (GDPR art. 15 to 21)."},"received_on":{"type":"string","description":"Date the company received the request (YYYY-MM-DD): the one-month period runs from it."},"requester_description":{"type":"string","minLength":10,"maxLength":2000,"description":"Who made the request and what was asked (e.g. \"a former customer asking for a copy of their order history\"); no sensitive data beyond what the request needs."},"channel":{"type":"string","maxLength":100,"description":"How the request arrived (e-mail, letter, phone, in person...)."},"notes":{"type":"string","maxLength":2000,"description":"Other context for the handling of the request."}},"required":["right","received_on","requester_description"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool result: `result` holds the structured data, `text` the same answer as plain text.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}}}},"401":{"description":"Missing or invalid key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown tool.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid arguments, a limit of the plan reached, or the tool could not complete the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests from this address; retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Temporarily unavailable; retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/tools/report_breach":{"post":{"operationId":"report_breach","summary":"Open a personal data breach","description":"Opens a personal data breach in the Hermetics space of the organization, with its code and the end of the 72-hour period to notify the supervisory authority (art. 33(1)), counted from when the company became aware of it. Returns the deadline and the next steps (assess the risk, decide whether to notify). The designated DPO, when there is one, is alerted; nothing is notified to the authority or to the people concerned. The free account tracks 10 breaches a year; the paid plans have no limit. Prepared from the facts given; the decision is the user's, or the designated DPO validates it when the organization has one.","tags":["Records"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"discovered_at":{"type":"string","description":"When the company became aware of the breach (ISO 8601 date and time with time zone): the 72-hour period runs from it."},"description":{"type":"string","minLength":20,"maxLength":4000,"description":"What happened, the systems involved and the measures already taken; no personal data needed."},"data_categories":{"type":"array","items":{"type":"string","minLength":1,"maxLength":200},"maxItems":30,"description":"Categories of personal data concerned, e.g. \"identity\", \"bank details\"."},"people_count_estimate":{"type":"integer","minimum":0,"maximum":1000000000,"description":"Approximate number of people concerned."},"ongoing":{"type":"boolean","description":"True if the breach is still ongoing."}},"required":["discovered_at","description"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool result: `result` holds the structured data, `text` the same answer as plain text.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}}}},"401":{"description":"Missing or invalid key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown tool.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid arguments, a limit of the plan reached, or the tool could not complete the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests from this address; retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Temporarily unavailable; retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/mcp":{"post":{"operationId":"mcp_jsonrpc","summary":"MCP server (JSON-RPC 2.0, Streamable HTTP, stateless)","description":"The same tools for AI assistants that speak the Model Context Protocol: initialize, tools/list and tools/call. tools/call needs an account (OAuth 2.1 with an e-mail code, or a key).","tags":["MCP"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["jsonrpc","method"],"properties":{"jsonrpc":{"type":"string","enum":["2.0"]},"id":{"type":["string","integer"]},"method":{"type":"string","enum":["initialize","ping","tools/list","tools/call"]},"params":{"type":"object"}}}}}},"responses":{"200":{"description":"A JSON-RPC 2.0 response.","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"tools/call without an account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"A Hermetics key (hk_...), created at https://hermetics.fr/mcp/cle with a free account."}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","description":"Stable error code: unauthorized, unknown_tool, tool_error, request_failed, not_found."},"message":{"type":"string","description":"What went wrong."},"hint":{"type":"string","description":"What to do next."}}}}},"ToolResult":{"type":"object","required":["result","text"],"properties":{"result":{"type":["object","null"],"description":"Structured data returned by the tool."},"text":{"type":"string","description":"The same answer as plain text."}}}}}}