Install an app in a project
A team owner, admin or developer of the project, and Ivora administrators; another team's first_party app only the project team's owners and admins (403 for a developer). Send the scopes you accept (a subset of the app's request, each one you hold yourself) and the consent_revision from the consent view. 409 consent_outdated when the app changed since; 409 app_already_installed. An Ivora administrator outside the project's team installs only on the project's request and sends a reason (422 staff_reason_required without it), kept as the install's staff_reason; every install is recorded in the project's audit trail (app.installed).
Path parameters
- tenant_idintegerRequired
- app_idstringRequiredPattern
^app_[0-9a-f]{32}$
Request body
- scopesarray of stringRequiredThe scopes the consent screen showed and the installer accepted: a subset of the app's requested scopes.
- consent_revisionintegerRequiredThe app's revision from the consent screen; 409 consent_outdated when the app changed since.Minimum 1
- reasonstring | nullIvora administrators installing in a project outside their own team, on the project's request: why, kept with the install and in the project's audit trail (422 staff_reason_required without it). Ignored for the project's own team.3–300 characters
Returns · 201
- idstringRequired
- app_idstringRequired
- app_namestring | null
- tenant_idintegerRequired
- scopesarray of stringRequiredWhat the app holds in this project: its consented scopes, never more than the app requests.
- consent_revisionintegerRequired
- rate_limit_per_minuteintegerRequired
- statusenumRequiredOne of
active,revoked - installed_bystringRequired
- installed_atstringRequired
- updated_atstringRequired
- revoked_atstring | nullRequired
- revoked_bystring | nullRequired
- revoked_reasonstring | nullRequireduninstalled or app_archived.
- staff_reasonstring | nullSet when Ivora staff installed the app on the project's request: why. Null for an install by the project's own team.
curl --fail-with-body -X POST "https://api.ivoracharge.com/v1/tenants/1042/apps/app_0123456789abcdef0123456789abcdef/install" \
-H "Authorization: Bearer $IVORA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"scopes": [
"string"
],
"consent_revision": 1
}'{
"id": "id_0123456789abcdef",
"app_id": "app_0123456789abcdef",
"app_name": "string",
"tenant_id": 1042,
"scopes": [
"string"
],
"consent_revision": 1,
"rate_limit_per_minute": 1,
"status": "active",
"installed_by": "string",
"installed_at": "2026-09-30T17:00:00Z",
"updated_at": "2026-09-30T17:00:00Z",
"revoked_at": "2026-09-30T17:00:00Z",
"revoked_by": "string",
"revoked_reason": "string",
"staff_reason": "string"
}Try itproduction · api.ivoracharge.com
Paste a production api key (iv_live_…). Create keys in Developer tools. The key stays in this page's memory, is sent only to https://api.ivoracharge.com and clears when you reload. Test keys are refused.
POST is a write: you confirm the method, path and project before it is sent, with a generated Idempotency-Key.



