Skip to content

Set up organisations and whistleblowing channels

Setup uses two write scopes. Neither is preselected: choose them when you create a token. Scopes cannot be added to an existing token.

  • organizations:create creates organisations. Only personal tokens can hold it, because a new organisation belongs to a person: you become its owner and administrator.
  • channel:write reads and changes channel configuration. On a personal token it works only where you are a current administrator; it never promotes a member or viewer. On an organisation token, an administrator granted it when creating the token, so the scope alone applies.

Creating a token requires fresh authentication. Tokens cannot issue tokens or accept agreements. Webhooks, invitations and billing links each have their own scope. Authentication and permissions.

Your token owner must have at least one active membership and must have accepted the current account terms. An assistant connection is the exception: a person with no organisation can create their first one through it.

Terminal window
curl --fail-with-body \
-X POST \
-H "Authorization: Bearer $ETHICSPORTAL_TOKEN" \
-H 'Content-Type: application/json' \
-H "Idempotency-Key: $(uuidgen)" \
--data '{"organization":{"name":"Example organisation"}}' \
"$ETHICSPORTAL_ORIGIN/organizations.json"

A 201 response contains:

{
"id": "gHiJkl",
"name": "Example organisation",
"membership_id": "mAbCde",
"channel": { "id": "AB12CD34", "active": false }
}

The token owner becomes the organisation owner and an administrator. Its default whistleblowing channel is created automatically. Treat all IDs as strings. Save id as ETHICSPORTAL_ORGANIZATION_ID and membership_id for appointing yourself as compliance officer.

Creation does not start a subscription or accept the DPA. The new organisation is reachable through the API at once, but its owner must accept the current organisation agreement in EthicsPortal before configuration requests can succeed. The Location response header points to the organisation’s web page, which requires a separate browser session.

Send an Idempotency-Key header with each creation, as in the example. If the response is lost, repeat the request with the same key: you get the first response back instead of a second organisation. Without a key, a lost response may still mean the organisation was created, so check before retrying. Safe retries. Names need not be unique. Organisation creation allows up to ten attempts per user per minute, shared across tokens.

Terminal window
curl --fail-with-body \
-H "Authorization: Bearer $ETHICSPORTAL_TOKEN" \
"$ETHICSPORTAL_ORIGIN/organizations/$ETHICSPORTAL_ORGANIZATION_ID/whistleblower/portal/configuration.json"

This privileged resource returns company details, channel settings, the compliance officer’s obfuscated membership ID, public reporting form URL, verification state, missing_fields and derived active state. It requires channel:write even for GET. Ordinary channel metadata remains limited to its identifier, active state and public form URL.

Send only the fields you want to change. Use native JSON booleans and numbers. Unknown attributes, nested values, additional top-level objects and query parameters are rejected with 400 invalid_request.

Terminal window
curl --fail-with-body \
-X PATCH \
-H "Authorization: Bearer $ETHICSPORTAL_TOKEN" \
-H 'Content-Type: application/json' \
--data '{"portal":{
"legal_name":"Example company",
"country_code":"FR",
"registration_number":"EXAMPLE-123",
"address":"1 Example Street",
"employee_range":"1-49",
"industry":"professional_scientific_services",
"retention_months":60,
"compliance_officer_id":"mAbCde",
"social_dialogue_consulted":true,
"voice_recording_enabled":false,
"email_intake_enabled":false,
"brand_color":"#123456"
}}' \
"$ETHICSPORTAL_ORIGIN/organizations/$ETHICSPORTAL_ORGANIZATION_ID/whistleblower/portal/configuration.json"

Additional optional fields are phone_number and website. The API reference lists types and supported values. Use the membership_id returned by creation to appoint yourself. Other officers must already be active administrators in the same organisation; obtain their obfuscated membership ID from your authorised team workflow. Raw database IDs are rejected.

Settings obey the same model rules as the application:

  • Verified company details are locked. The API cannot grant or remove verification.
  • Retention must be an offered value and meet the country’s minimum. Change the country and retention together when needed.
  • Compliance officers must be active administrators in the organisation.
  • Removing required information, including setting the compliance officer to null, can make the channel inactive.
  • active is derived from complete required information and existing subscription or granted access. It cannot be set directly. A successful save does not guarantee activation.

The API does not create missing channels during GET or PATCH. A normal organisation creation already creates one; a missing channel returns 404.

A model validation failure returns 422 and the affected field names, without echoing submitted values:

{"error":{"code":"validation_failed","fields":["retention_months"],"feedback_url":"https://secure.ethicsportal.eu/me/feedback.json"}}

base indicates a record-level restriction, such as locked verified company details. A non-administrator compliance officer can be reported as compliance_officer. No partial settings are saved on validation failure. Errors and rate limits.

All report-content exclusions continue to apply. There is no report submission, report mutation or agreement-acceptance API. After setup, the API also manages webhooks, and sends invitations and creates subscription checkout links: Administration. Changing a member’s role and removing a member stay in the web application.