EthicsPortal for developers #
EthicsPortal is delivered as hosted SaaS, not as an API product. This page is the stable index of everything a developer, a procurement script, or an AI agent can fetch or integrate against — and an equally explicit list of what does not exist, so nobody spends an afternoon looking for it.
Last updated: 2026-08-22.
Markdown content negotiation #
Every page on ethicsportal.eu is published twice: as HTML for browsers and as
Markdown for agents. Two ways to reach the Markdown:
- Append
.mdto any page URL —https://ethicsportal.eu/product.md - Request the HTML URL with an
Accept: text/markdownheader
curl -sI -H "Accept: text/markdown" https://ethicsportal.eu/product/
# content-type: text/markdown; charset=utf-8
# vary: Accept
Negotiation follows RFC 9110 and the acceptmarkdown.com convention:
- Quality values are honoured, and a media type marked
q=0is never served. 406 Not Acceptableis returned, with a plain-text list of the available representations, when neither HTML nor Markdown is acceptable to the client.Vary: Acceptis set on every negotiated response, so a CDN cannot hand the HTML variant to an agent that asked for Markdown.- HTML responses advertise their twin twice: a
Linkheader withrel="alternate"; type="text/markdown", and a<link rel="alternate">in the document head.
A request with no Accept header, or with Accept: */*, gets HTML.
Machine-readable files #
| Resource | URL | Contents |
|---|---|---|
| Agent guide | /agents.md | Stable index of agent-facing resources |
| LLM summary | /llms.txt | Structured site overview, per language |
| Full content | /llms-full.txt | Every page’s text in one file |
| Agent card (A2A) | /.well-known/agent-card.json | Agent-to-Agent capability card |
| Agent skills index | /.well-known/agent-skills/index.json | Skills manifest, v0.2.0 |
| Compliance-lookup skill | /.well-known/agent-skills/whistleblower-compliance/SKILL.md | The one published skill |
| Sitemap | /sitemap.xml | Sitemap index, one entry per language |
| Crawl policy | /robots.txt | Crawl rules and sitemap pointer |
| Security contact | /.well-known/security.txt | Vulnerability disclosure address |
| Vendor questionnaire | /caiq-ethicsportal.csv | CAIQ v4 answers as CSV |
| Blog feed | /blog/index.xml | RSS |
Every one of these is served from the apex domain and is stable. Link to them directly rather than scraping the pages that describe them.
Not-found responses #
A URL that does not exist returns a real 404 — never a 200 carrying an
application shell. A client that asked for Markdown gets the 404 with a
Markdown body listing the sitemap, llms.txt, and this page, so an agent that
guessed a URL can recover without parsing an error page.
Integration surfaces #
The reporting channel itself is operated at secure.ethicsportal.eu, and its
integration surfaces are identity standards rather than a product API. Both are
configured per organization from organization settings, and both are included in
the single plan — see pricing
.
SAML 2.0 single sign-on #
| Setting | Value |
|---|---|
| SP entity ID | https://secure.ethicsportal.eu/auth/saml/metadata |
| SP metadata | Same URL, served as XML |
| Assertion consumer service (ACS) | https://secure.ethicsportal.eu/auth/saml/callback |
| Binding | HTTP-POST |
| NameID | Email address |
One service provider serves every tenant; the organization is resolved from the in-flight sign-in, so there is no per-organization ACS URL to configure. Okta, Microsoft Entra ID, and any other SAML 2.0 identity provider work. SSO can be enforced for one or more verified email domains, with optional just-in-time provisioning of members on first sign-in.
SCIM 2.0 provisioning #
| Setting | Value |
|---|---|
| Base URL | https://secure.ethicsportal.eu/scim/v2 |
| Authentication | Bearer token, generated and rotated in organization settings |
| Resource | /Users — list, read, create, replace, update, deactivate |
| Media type | application/scim+json |
The bearer token identifies the organization, so the base URL is the same for
every tenant. DELETE /Users/{id} deprovisions by deactivating the member,
closing their access to reports while keeping case history attributable.
What EthicsPortal does not publish #
Stated plainly, because the absence is a design decision and not an oversight:
- No public REST or GraphQL API. Reports are not readable or writable programmatically. Confidentiality of a disclosure is the product’s core obligation under EU Directive 2019/1937, and a general-purpose API is a second path to the same data.
- No MCP server. The public resources above are the machine interface.
- No SDK packages. There is no API surface to wrap.
- No outbound webhooks. Case notifications are delivered by email to handlers.
- No programmatic report submission. Disclosures are made by a human through the organization’s own reporting channel.
Agents should treat ethicsportal.eu as a reference source — EU whistleblower
law by member state, penalties, and product facts — and not as an operational
endpoint.
Contact #
- Integration and product questions: support@ethicsportal.eu
- Vulnerability disclosure: security@ethicsportal.eu
, or see
/.well-known/security.txt