From 58f8706e2149a9918e106ddf8940235fa0d8543b Mon Sep 17 00:00:00 2001 From: samiFakhfakhScalingo Date: Tue, 23 Dec 2025 11:04:05 +0100 Subject: [PATCH 01/14] feat(project_transfert): add new endpoints --- _scalingo_api/projects.md | 232 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 232 insertions(+) diff --git a/_scalingo_api/projects.md b/_scalingo_api/projects.md index 0f795aa..3695668 100644 --- a/_scalingo_api/projects.md +++ b/_scalingo_api/projects.md @@ -291,3 +291,235 @@ Returns 204 No Content ```json {} ``` + +--- row --- + +## Project transfer invitations + +--- row --- + +`GET https://$SCALINGO_API_URL/v1/projects/[:project_id]/transfer_invitations` + +Project transfer invitations let a project owner transfer ownership to another collaborator. Each invitation automatically expires after 3 days and includes a token that can be used in Dashboard links such as `projects/transfers?token=:token`. + +By default only `pending` invitations are returned. Pass the `status` query parameter (for example `?status=all`) to disable the pending-only filter. + +||| col ||| + +**Transfer invitation attributes** + +{:.table} +| field | type | description | +| --------------- | ------- | -------------------------------------------------------------------------- | +| id | string | unique ID of the invitation | +| project_id | string | ID of the project targeted by the transfer | +| invited_user | object | invited collaborator | +| inviter | object | user who created the invitation | +| status | string | one of `pending`, `accepted`, `declined`, `canceled`, `failed` | +| status_reason | string | optional rationale for the current status | +| token | string | token usable in Dashboard transfer links | +| expires_at | date | expiration date of the invitation | +| created_at | date | creation date | +| updated_at | date | last update date | + +||| col ||| + +Example request + +```shell +curl -H "Accept: application/json" -H "Content-Type: application/json" \ + -H "Authorization: Bearer $BEARER_TOKEN" \ + -X GET https://$SCALINGO_API_URL/v1/projects/pr-82a3cac5-9b25-473e-b33d-6272b87e636f/transfer_invitations +``` + +Returns 200 OK + +```json +{ + "transfer_invitations": [ + { + "id": "tin-01234567-89ab-cdef-0123-456789abcdef", + "project_id": "pr-82a3cac5-9b25-473e-b33d-6272b87e636f", + "invited_user": { + "id": "54100245736f7563d5000000", + "username": "alice", + "email": "alice@example.com" + }, + "inviter": { + "id": "54100245736f7563d5000000", + "username": "john", + "email": "user@example.com" + }, + "status": "pending", + "status_reason": "Please confirm the transfer.", + "token": "transfer-token-abc123", + "expires_at": "2014-09-13T10:17:52.690+02:00", + "created_at": "2014-09-10T10:17:52.690+02:00", + "updated_at": "2014-09-10T10:17:52.690+02:00" + } + ] +} +``` + +--- row --- + +## Get a project transfer invitation + +--- row --- + +`GET https://$SCALINGO_API_URL/v1/projects/[:project_id]/transfer_invitations/[:id]` + +Retrieve a specific project transfer invitation. The invitation is visible to the inviter or the invited collaborator. + +||| col ||| + +Example request + +```shell +curl -H "Accept: application/json" -H "Content-Type: application/json" \ + -H "Authorization: Bearer $BEARER_TOKEN" \ + -X GET https://$SCALINGO_API_URL/v1/projects/pr-82a3cac5-9b25-473e-b33d-6272b87e636f/transfer_invitations/tin-01234567-89ab-cdef-0123-456789abcdef +``` + +Returns 200 OK + +```json +{ + "transfer_invitation": { + "id": "tin-01234567-89ab-cdef-0123-456789abcdef", + "project_id": "pr-82a3cac5-9b25-473e-b33d-6272b87e636f", + "invited_user": { + "id": "54100245736f7563d5000000", + "username": "alice", + "email": "alice@example.com" + }, + "inviter": { + "id": "54100245736f7563d5000000", + "username": "john", + "email": "user@example.com" + }, + "status": "pending", + "status_reason": "Please confirm the transfer.", + "token": "transfer-token-abc123", + "expires_at": "2014-09-13T10:17:52.690+02:00", + "created_at": "2014-09-10T10:17:52.690+02:00", + "updated_at": "2014-09-10T10:17:52.690+02:00" + } +} +``` + +--- row --- + +## Create a project transfer invitation + +--- row --- + +`POST https://$SCALINGO_API_URL/v1/projects/[:project_id]/transfer_invitations` + +Project owners can create a transfer invitation for a collaborator who has access to all applications in the project. The API sets the expiration (`expires_at`) to `now + 3 days` and fails if a `pending` invitation already exists for the project. + +### Parameters + +* `transfer_invitation.invited_user_id`: ID of the collaborator to invite +* `transfer_invitation.status_reason`: (*Optional*) rationale for the invitation + +||| col ||| + +Example request + +```shell +curl -H "Accept: application/json" -H "Content-Type: application/json" \ + -H "Authorization: Bearer $BEARER_TOKEN" \ + -X POST https://$SCALINGO_API_URL/v1/projects/pr-82a3cac5-9b25-473e-b33d-6272b87e636f/transfer_invitations -d \ + '{ + "transfer_invitation": { + "invited_user_id": "54100245736f7563d5000000", + "status_reason": "Transfer ownership to alice" + } + }' +``` + +Returns 201 Created + +```json +{ + "transfer_invitation": { + "id": "tin-01234567-89ab-cdef-0123-456789abcdef", + "project_id": "pr-82a3cac5-9b25-473e-b33d-6272b87e636f", + "invited_user": { + "id": "54100245736f7563d5000000", + "username": "alice", + "email": "alice@example.com" + }, + "inviter": { + "id": "54100245736f7563d5000000", + "username": "john", + "email": "user@example.com" + }, + "status": "pending", + "status_reason": "Transfer ownership to alice", + "token": "transfer-token-abc123", + "expires_at": "2014-09-13T10:17:52.690+02:00", + "created_at": "2014-09-10T10:17:52.690+02:00", + "updated_at": "2014-09-10T10:17:52.690+02:00" + } +} +``` + +--- row --- + +## Update a project transfer invitation + +--- row --- + +`PATCH https://$SCALINGO_API_URL/v1/projects/[:project_id]/transfer_invitations/[:id]` + +The inviter or invited collaborator can update the status of a project transfer invitation. + +### Parameters + +* `transfer_invitation.status`: one of `pending`, `accepted`, `declined`, `canceled`, `failed` +* `transfer_invitation.status_reason`: (*Optional*) rationale for the status + +||| col ||| + +Example request + +```shell +curl -H "Accept: application/json" -H "Content-Type: application/json" \ + -H "Authorization: Bearer $BEARER_TOKEN" \ + -X PATCH https://$SCALINGO_API_URL/v1/projects/pr-82a3cac5-9b25-473e-b33d-6272b87e636f/transfer_invitations/tin-01234567-89ab-cdef-0123-456789abcdef -d \ + '{ + "transfer_invitation": { + "status": "accepted", + "status_reason": "Confirmed ownership transfer" + } + }' +``` + +Returns 200 OK + +```json +{ + "transfer_invitation": { + "id": "tin-01234567-89ab-cdef-0123-456789abcdef", + "project_id": "pr-82a3cac5-9b25-473e-b33d-6272b87e636f", + "invited_user": { + "id": "54100245736f7563d5000000", + "username": "alice", + "email": "alice@example.com" + }, + "inviter": { + "id": "54100245736f7563d5000000", + "username": "john", + "email": "user@example.com" + }, + "status": "accepted", + "status_reason": "Confirmed ownership transfer", + "token": "transfer-token-abc123", + "expires_at": "2014-09-13T10:17:52.690+02:00", + "created_at": "2014-09-10T10:17:52.690+02:00", + "updated_at": "2014-09-10T11:00:00.000+02:00" + } +} +``` From 6306e43f1806cca0cba91981d97e9918bd3899dc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Jan 2026 09:11:03 +0100 Subject: [PATCH 02/14] chore(deps): bump prism from 1.6.0 to 1.7.0 (#609) Bumps [prism](https://github.com/ruby/prism) from 1.6.0 to 1.7.0. - [Release notes](https://github.com/ruby/prism/releases) - [Changelog](https://github.com/ruby/prism/blob/main/CHANGELOG.md) - [Commits](https://github.com/ruby/prism/compare/v1.6.0...v1.7.0) --- updated-dependencies: - dependency-name: prism dependency-version: 1.7.0 dependency-type: indirect update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 4c9ee4f..ba7a24e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -83,7 +83,7 @@ GEM racc pathutil (0.16.2) forwardable-extended (~> 2.6) - prism (1.6.0) + prism (1.7.0) public_suffix (7.0.0) puma (7.1.0) nio4r (~> 2.0) From b24c3df92cf4b2593a2678c183ef505a36e0c70c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Jan 2026 09:11:17 +0100 Subject: [PATCH 03/14] chore(deps): bump rouge from 4.6.1 to 4.7.0 (#611) Bumps [rouge](https://github.com/rouge-ruby/rouge) from 4.6.1 to 4.7.0. - [Release notes](https://github.com/rouge-ruby/rouge/releases) - [Changelog](https://github.com/rouge-ruby/rouge/blob/master/CHANGELOG.md) - [Commits](https://github.com/rouge-ruby/rouge/compare/v4.6.1...v4.7.0) --- updated-dependencies: - dependency-name: rouge dependency-version: 4.7.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index ba7a24e..11b5307 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -97,7 +97,7 @@ GEM ffi (~> 1.0) regexp_parser (2.11.3) rexml (3.4.4) - rouge (4.6.1) + rouge (4.7.0) rubocop (1.81.7) json (~> 2.3) language_server-protocol (~> 3.17.0.2) From f1f6430dcdac5f1fa34d1847675c3be4252271d3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Jan 2026 09:11:32 +0100 Subject: [PATCH 04/14] chore(deps): bump ffi from 1.17.2 to 1.17.3 (#613) Bumps [ffi](https://github.com/ffi/ffi) from 1.17.2 to 1.17.3. - [Changelog](https://github.com/ffi/ffi/blob/master/CHANGELOG.md) - [Commits](https://github.com/ffi/ffi/compare/v1.17.2...v1.17.3) --- updated-dependencies: - dependency-name: ffi dependency-version: 1.17.3 dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 11b5307..82b06b6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -22,7 +22,7 @@ GEM eventmachine (>= 0.12.9) http_parser.rb (~> 0) eventmachine (1.2.7) - ffi (1.17.2) + ffi (1.17.3) forwardable-extended (2.6.0) google-protobuf (4.33.2) bigdecimal From e9420b32d9144c4ad001cad5cee1259f975e853c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Jan 2026 09:11:45 +0100 Subject: [PATCH 05/14] chore(deps): bump rubocop-ast from 1.48.0 to 1.49.0 (#615) Bumps [rubocop-ast](https://github.com/rubocop/rubocop-ast) from 1.48.0 to 1.49.0. - [Release notes](https://github.com/rubocop/rubocop-ast/releases) - [Changelog](https://github.com/rubocop/rubocop-ast/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop-ast/compare/v1.48.0...v1.49.0) --- updated-dependencies: - dependency-name: rubocop-ast dependency-version: 1.49.0 dependency-type: indirect update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 82b06b6..9be03db 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -109,9 +109,9 @@ GEM rubocop-ast (>= 1.47.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 4.0) - rubocop-ast (1.48.0) + rubocop-ast (1.49.0) parser (>= 3.3.7.2) - prism (~> 1.4) + prism (~> 1.7) rubocop-performance (1.25.0) lint_roller (~> 1.1) rubocop (>= 1.75.0, < 2.0) From 8f9b9fac2566f51fa772d65fb65cc3ff45ef9fa3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Jan 2026 09:11:59 +0100 Subject: [PATCH 06/14] chore(deps): bump concurrent-ruby from 1.3.5 to 1.3.6 (#616) Bumps [concurrent-ruby](https://github.com/ruby-concurrency/concurrent-ruby) from 1.3.5 to 1.3.6. - [Release notes](https://github.com/ruby-concurrency/concurrent-ruby/releases) - [Changelog](https://github.com/ruby-concurrency/concurrent-ruby/blob/master/CHANGELOG.md) - [Commits](https://github.com/ruby-concurrency/concurrent-ruby/compare/v1.3.5...v1.3.6) --- updated-dependencies: - dependency-name: concurrent-ruby dependency-version: 1.3.6 dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 9be03db..5d38efb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -16,7 +16,7 @@ GEM base64 (0.3.0) bigdecimal (3.3.1) colorator (1.1.0) - concurrent-ruby (1.3.5) + concurrent-ruby (1.3.6) csv (3.3.5) em-websocket (0.5.3) eventmachine (>= 0.12.9) From 63a156e82eeab2396196c9b028c513f3acf6c3eb Mon Sep 17 00:00:00 2001 From: samiFakhfakhScalingo Date: Wed, 7 Jan 2026 09:21:26 +0100 Subject: [PATCH 07/14] remove usage of token --- _scalingo_api/projects.md | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/_scalingo_api/projects.md b/_scalingo_api/projects.md index 3695668..0bf8750 100644 --- a/_scalingo_api/projects.md +++ b/_scalingo_api/projects.md @@ -300,7 +300,7 @@ Returns 204 No Content `GET https://$SCALINGO_API_URL/v1/projects/[:project_id]/transfer_invitations` -Project transfer invitations let a project owner transfer ownership to another collaborator. Each invitation automatically expires after 3 days and includes a token that can be used in Dashboard links such as `projects/transfers?token=:token`. +Project transfer invitations let a project owner transfer ownership to another collaborator. By default only `pending` invitations are returned. Pass the `status` query parameter (for example `?status=all`) to disable the pending-only filter. @@ -317,7 +317,6 @@ By default only `pending` invitations are returned. Pass the `status` query para | inviter | object | user who created the invitation | | status | string | one of `pending`, `accepted`, `declined`, `canceled`, `failed` | | status_reason | string | optional rationale for the current status | -| token | string | token usable in Dashboard transfer links | | expires_at | date | expiration date of the invitation | | created_at | date | creation date | | updated_at | date | last update date | @@ -352,7 +351,6 @@ Returns 200 OK }, "status": "pending", "status_reason": "Please confirm the transfer.", - "token": "transfer-token-abc123", "expires_at": "2014-09-13T10:17:52.690+02:00", "created_at": "2014-09-10T10:17:52.690+02:00", "updated_at": "2014-09-10T10:17:52.690+02:00" @@ -400,7 +398,6 @@ Returns 200 OK }, "status": "pending", "status_reason": "Please confirm the transfer.", - "token": "transfer-token-abc123", "expires_at": "2014-09-13T10:17:52.690+02:00", "created_at": "2014-09-10T10:17:52.690+02:00", "updated_at": "2014-09-10T10:17:52.690+02:00" @@ -458,7 +455,6 @@ Returns 201 Created }, "status": "pending", "status_reason": "Transfer ownership to alice", - "token": "transfer-token-abc123", "expires_at": "2014-09-13T10:17:52.690+02:00", "created_at": "2014-09-10T10:17:52.690+02:00", "updated_at": "2014-09-10T10:17:52.690+02:00" @@ -516,7 +512,6 @@ Returns 200 OK }, "status": "accepted", "status_reason": "Confirmed ownership transfer", - "token": "transfer-token-abc123", "expires_at": "2014-09-13T10:17:52.690+02:00", "created_at": "2014-09-10T10:17:52.690+02:00", "updated_at": "2014-09-10T11:00:00.000+02:00" From 379133dddeb48bf85ebc973b06d4c38105cca0bd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Jan 2026 09:56:58 +0100 Subject: [PATCH 08/14] chore(deps): bump rubocop-performance from 1.25.0 to 1.26.1 (#618) Bumps [rubocop-performance](https://github.com/rubocop/rubocop-performance) from 1.25.0 to 1.26.1. - [Release notes](https://github.com/rubocop/rubocop-performance/releases) - [Changelog](https://github.com/rubocop/rubocop-performance/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop-performance/compare/v1.25.0...v1.26.1) --- updated-dependencies: - dependency-name: rubocop-performance dependency-version: 1.26.1 dependency-type: indirect update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 5d38efb..63a87f0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -60,7 +60,7 @@ GEM nokogiri (~> 1.12) jekyll-watch (2.2.1) listen (~> 3.0) - json (2.17.1) + json (2.18.0) kramdown (2.5.1) rexml (>= 3.3.9) kramdown-parser-gfm (1.1.0) @@ -112,10 +112,10 @@ GEM rubocop-ast (1.49.0) parser (>= 3.3.7.2) prism (~> 1.7) - rubocop-performance (1.25.0) + rubocop-performance (1.26.1) lint_roller (~> 1.1) rubocop (>= 1.75.0, < 2.0) - rubocop-ast (>= 1.38.0, < 2.0) + rubocop-ast (>= 1.47.1, < 2.0) ruby-progressbar (1.13.0) safe_yaml (1.0.5) sass-embedded (1.94.2) @@ -130,9 +130,9 @@ GEM standard-custom (1.0.2) lint_roller (~> 1.0) rubocop (~> 1.50) - standard-performance (1.8.0) + standard-performance (1.9.0) lint_roller (~> 1.1) - rubocop-performance (~> 1.25.0) + rubocop-performance (~> 1.26.0) terminal-table (3.0.2) unicode-display_width (>= 1.1.1, < 3) unicode-display_width (2.6.0) From 5d1fb127ffab41fba853da2c15ef7ac445bb0373 Mon Sep 17 00:00:00 2001 From: samiFakhfakhScalingo Date: Fri, 9 Jan 2026 12:23:02 +0100 Subject: [PATCH 09/14] add decline doc --- _scalingo_api/projects.md | 46 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/_scalingo_api/projects.md b/_scalingo_api/projects.md index 0bf8750..f6c95bb 100644 --- a/_scalingo_api/projects.md +++ b/_scalingo_api/projects.md @@ -518,3 +518,49 @@ Returns 200 OK } } ``` + +--- row --- + +## Decline a project transfer invitation (member of project) + +--- row --- + +`POST https://$SCALINGO_API_URL/v1/projects/[:project_id]/transfer_invitations/[:id]/decline` + +The invited collaborator can decline a project transfer invitation. + +||| col ||| + +Example request + +```shell +curl -H "Accept: application/json" -H "Content-Type: application/json" \ + -H "Authorization: Bearer $BEARER_TOKEN" \ + -X POST https://$SCALINGO_API_URL/v1/projects/pr-82a3cac5-9b25-473e-b33d-6272b87e636f/transfer_invitations/tin-01234567-89ab-cdef-0123-456789abcdef/decline +``` + +Returns 200 OK + +```json +{ + "transfer_invitation": { + "id": "tin-01234567-89ab-cdef-0123-456789abcdef", + "project_id": "pr-82a3cac5-9b25-473e-b33d-6272b87e636f", + "invited_user": { + "id": "54100245736f7563d5000000", + "username": "alice", + "email": "alice@example.com" + }, + "inviter": { + "id": "54100245736f7563d5000000", + "username": "john", + "email": "user@example.com" + }, + "status": "declined", + "status_reason": "Declined by invited collaborator", + "expires_at": "2014-09-13T10:17:52.690+02:00", + "created_at": "2014-09-10T10:17:52.690+02:00", + "updated_at": "2014-09-10T11:00:00.000+02:00" + } +} +``` From a6db3930eff124f8cbad008388546c37b51388ab Mon Sep 17 00:00:00 2001 From: samiFakhfakhScalingo Date: Fri, 9 Jan 2026 13:46:25 +0100 Subject: [PATCH 10/14] [STORY-2768] Add events --- _scalingo_api/events.md | 194 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) diff --git a/_scalingo_api/events.md b/_scalingo_api/events.md index 6c9d5dc..fabc9fe 100644 --- a/_scalingo_api/events.md +++ b/_scalingo_api/events.md @@ -2111,6 +2111,200 @@ Example object: --- row --- +* **Project transfer invitation event base** + +_When:_ Common attributes for project transfer invitation events. + +{:.table} +| field | type | description | +| ----------------------------- | ------ | --------------------------------------------- | +| transfer_invitation_id | string | ID of the transfer invitation | +| invited_user.id | string | ID of the invited collaborator | +| invited_user.email | string | Email of the invited collaborator | +| invited_user.username | string | Username of the invited collaborator | +| inviter.id | string | ID of the inviter | +| inviter.email | string | Email of the inviter | +| inviter.username | string | Username of the inviter | +| status | string | Invitation status | +| status_reason | string | Optional status rationale | +| expires_at | date | Expiration date of the invitation | + +--- row --- + +* **Accept project transfer invitation event** + +_When:_ A project transfer invitation is accepted +`type=accept_project_transfer_invitation` + +||| col ||| + +Example object: + +```json +{ + "id": "650312574002c001afcdf988", + "created_at": "2023-09-14T14:01:59.916Z", + "project_id": "649e9d0389bca600016ea61b", + "project_name": "project-1", + "type": "accept_project_transfer_invitation", + "user": { + "username": "alice", + "email": "alice@example.com", + "id": "us-0e6d8e46-5cd0-42a4-acba-372b2be605ac" + }, + "type_data": { + "transfer_invitation_id": "tin-01234567-89ab-cdef-0123-456789abcdef", + "invited_user": { + "id": "54100245736f7563d5000000", + "username": "alice", + "email": "alice@example.com" + }, + "inviter": { + "id": "54100245736f7563d5000000", + "username": "john", + "email": "user@example.com" + }, + "status": "accepted", + "status_reason": "Confirmed ownership transfer", + "expires_at": "2014-09-13T10:17:52.690+02:00" + } +} +``` + +--- row --- + +* **Accept project transfer invitation error event** + +_When:_ Accepting a project transfer invitation fails +`type=accept_project_transfer_invitation_error` + +{:.table} +| field | type | description | +| ----- | ------ | -------------------------------- | +| error | string | Error message for the failure | + +||| col ||| + +Example object: + +```json +{ + "id": "650312574002c001afcdf988", + "created_at": "2023-09-14T14:01:59.916Z", + "project_id": "649e9d0389bca600016ea61b", + "project_name": "project-1", + "type": "accept_project_transfer_invitation_error", + "user": { + "username": "alice", + "email": "alice@example.com", + "id": "us-0e6d8e46-5cd0-42a4-acba-372b2be605ac" + }, + "type_data": { + "transfer_invitation_id": "tin-01234567-89ab-cdef-0123-456789abcdef", + "invited_user": { + "id": "54100245736f7563d5000000", + "username": "alice", + "email": "alice@example.com" + }, + "inviter": { + "id": "54100245736f7563d5000000", + "username": "john", + "email": "user@example.com" + }, + "status": "failed", + "status_reason": "Transfer ownership failed", + "expires_at": "2014-09-13T10:17:52.690+02:00", + "error": "Project transfer invitation already expired." + } +} +``` + +--- row --- + +* **Cancel project transfer invitation event** + +_When:_ A project transfer invitation is canceled by the inviter +`type=cancel_project_transfer_invitation` + +||| col ||| + +Example object: + +```json +{ + "id": "650312574002c001afcdf988", + "created_at": "2023-09-14T14:01:59.916Z", + "project_id": "649e9d0389bca600016ea61b", + "project_name": "project-1", + "type": "cancel_project_transfer_invitation", + "user": { + "username": "john", + "email": "user@example.com", + "id": "us-0e6d8e46-5cd0-42a4-acba-372b2be605ac" + }, + "type_data": { + "transfer_invitation_id": "tin-01234567-89ab-cdef-0123-456789abcdef", + "invited_user": { + "id": "54100245736f7563d5000000", + "username": "alice", + "email": "alice@example.com" + }, + "inviter": { + "id": "54100245736f7563d5000000", + "username": "john", + "email": "user@example.com" + }, + "status": "canceled", + "status_reason": "Canceled by inviter", + "expires_at": "2014-09-13T10:17:52.690+02:00" + } +} +``` + +--- row --- + +* **Decline project transfer invitation event** + +_When:_ A project transfer invitation is declined by the invited collaborator +`type=decline_project_transfer_invitation` + +||| col ||| + +Example object: + +```json +{ + "id": "650312574002c001afcdf988", + "created_at": "2023-09-14T14:01:59.916Z", + "project_id": "649e9d0389bca600016ea61b", + "project_name": "project-1", + "type": "decline_project_transfer_invitation", + "user": { + "username": "alice", + "email": "alice@example.com", + "id": "us-0e6d8e46-5cd0-42a4-acba-372b2be605ac" + }, + "type_data": { + "transfer_invitation_id": "tin-01234567-89ab-cdef-0123-456789abcdef", + "invited_user": { + "id": "54100245736f7563d5000000", + "username": "alice", + "email": "alice@example.com" + }, + "inviter": { + "id": "54100245736f7563d5000000", + "username": "john", + "email": "user@example.com" + }, + "status": "declined", + "status_reason": "Declined by invited collaborator", + "expires_at": "2014-09-13T10:17:52.690+02:00" + } +} +``` + +--- row --- + * **Project Deleted** _When:_ A project has been deleted From 65634b8cc96d4e5068db05ea68199d74703ba50e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 9 Jan 2026 14:00:15 +0100 Subject: [PATCH 11/14] chore(deps-dev): bump nokogiri from 1.18.10 to 1.19.0 (#612) Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.18.10 to 1.19.0. - [Release notes](https://github.com/sparklemotion/nokogiri/releases) - [Changelog](https://github.com/sparklemotion/nokogiri/blob/main/CHANGELOG.md) - [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.18.10...v1.19.0) --- updated-dependencies: - dependency-name: nokogiri dependency-version: 1.19.0 dependency-type: indirect update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 63a87f0..1188bc2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -74,7 +74,7 @@ GEM mercenary (0.4.0) mini_portile2 (2.8.9) nio4r (2.7.5) - nokogiri (1.18.10) + nokogiri (1.19.0) mini_portile2 (~> 2.8.2) racc (~> 1.4) parallel (1.27.0) From 97b1b6aa91b28b8ee9b600d214f459863c78fe9b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 9 Jan 2026 14:00:30 +0100 Subject: [PATCH 12/14] chore(deps): bump i18n from 1.14.7 to 1.14.8 (#617) Bumps [i18n](https://github.com/ruby-i18n/i18n) from 1.14.7 to 1.14.8. - [Release notes](https://github.com/ruby-i18n/i18n/releases) - [Changelog](https://github.com/ruby-i18n/i18n/blob/master/CHANGELOG.md) - [Commits](https://github.com/ruby-i18n/i18n/compare/v1.14.7...v1.14.8) --- updated-dependencies: - dependency-name: i18n dependency-version: 1.14.8 dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 1188bc2..7e9be44 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -28,7 +28,7 @@ GEM bigdecimal rake (>= 13) http_parser.rb (0.8.0) - i18n (1.14.7) + i18n (1.14.8) concurrent-ruby (~> 1.0) jekyll (4.4.1) addressable (~> 2.4) From 84e8be638dae79e1fc3ba3958be095b45235f9d9 Mon Sep 17 00:00:00 2001 From: Annabelle PELLIER Date: Fri, 9 Jan 2026 17:39:36 +0100 Subject: [PATCH 13/14] add accept --- _scalingo_api/projects.md | 46 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/_scalingo_api/projects.md b/_scalingo_api/projects.md index f6c95bb..d6c5675 100644 --- a/_scalingo_api/projects.md +++ b/_scalingo_api/projects.md @@ -521,6 +521,52 @@ Returns 200 OK --- row --- +## Accept a project transfer invitation (member of project) + +--- row --- + +`POST https://$SCALINGO_API_URL/v1/projects/[:project_id]/transfer_invitations/[:id]/accept` + +The invited collaborator can accept a project transfer invitation. + +||| col ||| + +Example request + +```shell +curl -H "Accept: application/json" -H "Content-Type: application/json" \ + -H "Authorization: Bearer $BEARER_TOKEN" \ + -X POST https://$SCALINGO_API_URL/v1/projects/pr-82a3cac5-9b25-473e-b33d-6272b87e636f/transfer_invitations/tin-01234567-89ab-cdef-0123-456789abcdef/accept +``` + +Returns 200 OK + +```json +{ + "transfer_invitation": { + "id": "tin-01234567-89ab-cdef-0123-456789abcdef", + "project_id": "pr-82a3cac5-9b25-473e-b33d-6272b87e636f", + "invited_user": { + "id": "54100245736f7563d5000000", + "username": "alice", + "email": "alice@example.com" + }, + "inviter": { + "id": "54100245736f7563d5000000", + "username": "john", + "email": "user@example.com" + }, + "status": "accepted", + "status_reason": "Accepted by invited collaborator", + "expires_at": "2014-09-13T10:17:52.690+02:00", + "created_at": "2014-09-10T10:17:52.690+02:00", + "updated_at": "2014-09-10T11:00:00.000+02:00" + } +} +``` + +--- row --- + ## Decline a project transfer invitation (member of project) --- row --- From 89de05e4fe15b0daaa68ca1eee27dc8c210da7db Mon Sep 17 00:00:00 2001 From: Annabelle PELLIER Date: Mon, 19 Jan 2026 14:59:12 +0100 Subject: [PATCH 14/14] fix format --- _scalingo_api/events.md | 8 +- _scalingo_api/projects.md | 174 ++++++++++++++++---------------------- 2 files changed, 76 insertions(+), 106 deletions(-) diff --git a/_scalingo_api/events.md b/_scalingo_api/events.md index fabc9fe..c8d7bf5 100644 --- a/_scalingo_api/events.md +++ b/_scalingo_api/events.md @@ -2126,7 +2126,7 @@ _When:_ Common attributes for project transfer invitation events. | inviter.email | string | Email of the inviter | | inviter.username | string | Username of the inviter | | status | string | Invitation status | -| status_reason | string | Optional status rationale | +| status_reason | string | Reason of transfer action failure | | expires_at | date | Expiration date of the invitation | --- row --- @@ -2165,7 +2165,7 @@ Example object: "email": "user@example.com" }, "status": "accepted", - "status_reason": "Confirmed ownership transfer", + "status_reason": "", "expires_at": "2014-09-13T10:17:52.690+02:00" } } @@ -2255,7 +2255,7 @@ Example object: "email": "user@example.com" }, "status": "canceled", - "status_reason": "Canceled by inviter", + "status_reason": "", "expires_at": "2014-09-13T10:17:52.690+02:00" } } @@ -2297,7 +2297,7 @@ Example object: "email": "user@example.com" }, "status": "declined", - "status_reason": "Declined by invited collaborator", + "status_reason": "", "expires_at": "2014-09-13T10:17:52.690+02:00" } } diff --git a/_scalingo_api/projects.md b/_scalingo_api/projects.md index d6c5675..4769c37 100644 --- a/_scalingo_api/projects.md +++ b/_scalingo_api/projects.md @@ -298,13 +298,8 @@ Returns 204 No Content --- row --- -`GET https://$SCALINGO_API_URL/v1/projects/[:project_id]/transfer_invitations` - Project transfer invitations let a project owner transfer ownership to another collaborator. -By default only `pending` invitations are returned. Pass the `status` query parameter (for example `?status=all`) to disable the pending-only filter. - -||| col ||| **Transfer invitation attributes** @@ -313,16 +308,46 @@ By default only `pending` invitations are returned. Pass the `status` query para | --------------- | ------- | -------------------------------------------------------------------------- | | id | string | unique ID of the invitation | | project_id | string | ID of the project targeted by the transfer | -| invited_user | object | invited collaborator | -| inviter | object | user who created the invitation | +| invited_user_id | string | invited collaborator | +| invited_user_name | string | username of the invited collaborator | +| inviter_user_id | string | user who created the invitation | | status | string | one of `pending`, `accepted`, `declined`, `canceled`, `failed` | -| status_reason | string | optional rationale for the current status | +| status_reason | string | reason of transfer action failure | | expires_at | date | expiration date of the invitation | | created_at | date | creation date | | updated_at | date | last update date | ||| col ||| +Example object: + +```json +{ + "id": "tin-01234567-89ab-cdef-0123-456789abcdef", + "project_id": "pr-82a3cac5-9b25-473e-b33d-6272b87e636f", + "invited_user_id": "54100245736f7563d5000000", + "invited_user_name": "alice", + "inviter_user_id": "54100245736f7563d5000000", + "status": "pending", + "status_reason": "", + "expires_at": "2014-09-13T10:17:52.690+02:00", + "created_at": "2014-09-10T10:17:52.690+02:00", + "updated_at": "2014-09-10T10:17:52.690+02:00" +} +``` + +--- row --- + +## List all your project transfer invitations + +--- row --- + +`GET https://$SCALINGO_API_URL/v1/projects/[:project_id]/transfer_invitations` + +By default only not expired `pending` invitations are returned. Pass the `status` query parameter (for example `?status=all`) to disable the pending-only filter. + +||| col ||| + Example request ```shell @@ -339,18 +364,11 @@ Returns 200 OK { "id": "tin-01234567-89ab-cdef-0123-456789abcdef", "project_id": "pr-82a3cac5-9b25-473e-b33d-6272b87e636f", - "invited_user": { - "id": "54100245736f7563d5000000", - "username": "alice", - "email": "alice@example.com" - }, - "inviter": { - "id": "54100245736f7563d5000000", - "username": "john", - "email": "user@example.com" - }, + "invited_user_id": "54100245736f7563d5000000", + "invited_user_name": "alice", + "inviter_user_id": "54100245736f7563d5000000", "status": "pending", - "status_reason": "Please confirm the transfer.", + "status_reason": "", "expires_at": "2014-09-13T10:17:52.690+02:00", "created_at": "2014-09-10T10:17:52.690+02:00", "updated_at": "2014-09-10T10:17:52.690+02:00" @@ -386,18 +404,11 @@ Returns 200 OK "transfer_invitation": { "id": "tin-01234567-89ab-cdef-0123-456789abcdef", "project_id": "pr-82a3cac5-9b25-473e-b33d-6272b87e636f", - "invited_user": { - "id": "54100245736f7563d5000000", - "username": "alice", - "email": "alice@example.com" - }, - "inviter": { - "id": "54100245736f7563d5000000", - "username": "john", - "email": "user@example.com" - }, + "invited_user_id": "54100245736f7563d5000000", + "invited_user_name": "alice", + "inviter_user_id": "54100245736f7563d5000000", "status": "pending", - "status_reason": "Please confirm the transfer.", + "status_reason": "", "expires_at": "2014-09-13T10:17:52.690+02:00", "created_at": "2014-09-10T10:17:52.690+02:00", "updated_at": "2014-09-10T10:17:52.690+02:00" @@ -418,7 +429,6 @@ Project owners can create a transfer invitation for a collaborator who has acces ### Parameters * `transfer_invitation.invited_user_id`: ID of the collaborator to invite -* `transfer_invitation.status_reason`: (*Optional*) rationale for the invitation ||| col ||| @@ -430,8 +440,7 @@ curl -H "Accept: application/json" -H "Content-Type: application/json" \ -X POST https://$SCALINGO_API_URL/v1/projects/pr-82a3cac5-9b25-473e-b33d-6272b87e636f/transfer_invitations -d \ '{ "transfer_invitation": { - "invited_user_id": "54100245736f7563d5000000", - "status_reason": "Transfer ownership to alice" + "invited_user_id": "54100245736f7563d5000000" } }' ``` @@ -443,18 +452,11 @@ Returns 201 Created "transfer_invitation": { "id": "tin-01234567-89ab-cdef-0123-456789abcdef", "project_id": "pr-82a3cac5-9b25-473e-b33d-6272b87e636f", - "invited_user": { - "id": "54100245736f7563d5000000", - "username": "alice", - "email": "alice@example.com" - }, - "inviter": { - "id": "54100245736f7563d5000000", - "username": "john", - "email": "user@example.com" - }, + "invited_user_id": "54100245736f7563d5000000", + "invited_user_name": "alice", + "inviter_user_id": "54100245736f7563d5000000", "status": "pending", - "status_reason": "Transfer ownership to alice", + "status_reason": "", "expires_at": "2014-09-13T10:17:52.690+02:00", "created_at": "2014-09-10T10:17:52.690+02:00", "updated_at": "2014-09-10T10:17:52.690+02:00" @@ -464,18 +466,13 @@ Returns 201 Created --- row --- -## Update a project transfer invitation +## Accept a project transfer invitation --- row --- -`PATCH https://$SCALINGO_API_URL/v1/projects/[:project_id]/transfer_invitations/[:id]` - -The inviter or invited collaborator can update the status of a project transfer invitation. - -### Parameters +`POST https://$SCALINGO_API_URL/v1/projects/[:project_id]/transfer_invitations/[:id]/accept` -* `transfer_invitation.status`: one of `pending`, `accepted`, `declined`, `canceled`, `failed` -* `transfer_invitation.status_reason`: (*Optional*) rationale for the status +The invited collaborator can accept a project transfer invitation. ||| col ||| @@ -484,13 +481,7 @@ Example request ```shell curl -H "Accept: application/json" -H "Content-Type: application/json" \ -H "Authorization: Bearer $BEARER_TOKEN" \ - -X PATCH https://$SCALINGO_API_URL/v1/projects/pr-82a3cac5-9b25-473e-b33d-6272b87e636f/transfer_invitations/tin-01234567-89ab-cdef-0123-456789abcdef -d \ - '{ - "transfer_invitation": { - "status": "accepted", - "status_reason": "Confirmed ownership transfer" - } - }' + -X POST https://$SCALINGO_API_URL/v1/projects/pr-82a3cac5-9b25-473e-b33d-6272b87e636f/transfer_invitations/tin-01234567-89ab-cdef-0123-456789abcdef/accept ``` Returns 200 OK @@ -500,18 +491,11 @@ Returns 200 OK "transfer_invitation": { "id": "tin-01234567-89ab-cdef-0123-456789abcdef", "project_id": "pr-82a3cac5-9b25-473e-b33d-6272b87e636f", - "invited_user": { - "id": "54100245736f7563d5000000", - "username": "alice", - "email": "alice@example.com" - }, - "inviter": { - "id": "54100245736f7563d5000000", - "username": "john", - "email": "user@example.com" - }, + "invited_user_id": "54100245736f7563d5000000", + "invited_user_name": "alice", + "inviter_user_id": "54100245736f7563d5000000", "status": "accepted", - "status_reason": "Confirmed ownership transfer", + "status_reason": "", "expires_at": "2014-09-13T10:17:52.690+02:00", "created_at": "2014-09-10T10:17:52.690+02:00", "updated_at": "2014-09-10T11:00:00.000+02:00" @@ -521,13 +505,13 @@ Returns 200 OK --- row --- -## Accept a project transfer invitation (member of project) +## Decline a project transfer invitation --- row --- -`POST https://$SCALINGO_API_URL/v1/projects/[:project_id]/transfer_invitations/[:id]/accept` +`POST https://$SCALINGO_API_URL/v1/projects/[:project_id]/transfer_invitations/[:id]/decline` -The invited collaborator can accept a project transfer invitation. +The invited collaborator can decline a project transfer invitation. ||| col ||| @@ -536,7 +520,7 @@ Example request ```shell curl -H "Accept: application/json" -H "Content-Type: application/json" \ -H "Authorization: Bearer $BEARER_TOKEN" \ - -X POST https://$SCALINGO_API_URL/v1/projects/pr-82a3cac5-9b25-473e-b33d-6272b87e636f/transfer_invitations/tin-01234567-89ab-cdef-0123-456789abcdef/accept + -X POST https://$SCALINGO_API_URL/v1/projects/pr-82a3cac5-9b25-473e-b33d-6272b87e636f/transfer_invitations/tin-01234567-89ab-cdef-0123-456789abcdef/decline ``` Returns 200 OK @@ -546,18 +530,11 @@ Returns 200 OK "transfer_invitation": { "id": "tin-01234567-89ab-cdef-0123-456789abcdef", "project_id": "pr-82a3cac5-9b25-473e-b33d-6272b87e636f", - "invited_user": { - "id": "54100245736f7563d5000000", - "username": "alice", - "email": "alice@example.com" - }, - "inviter": { - "id": "54100245736f7563d5000000", - "username": "john", - "email": "user@example.com" - }, - "status": "accepted", - "status_reason": "Accepted by invited collaborator", + "invited_user_id": "54100245736f7563d5000000", + "invited_user_name": "alice", + "inviter_user_id": "54100245736f7563d5000000", + "status": "declined", + "status_reason": "", "expires_at": "2014-09-13T10:17:52.690+02:00", "created_at": "2014-09-10T10:17:52.690+02:00", "updated_at": "2014-09-10T11:00:00.000+02:00" @@ -567,13 +544,13 @@ Returns 200 OK --- row --- -## Decline a project transfer invitation (member of project) +## Cancel a project transfer invitation --- row --- -`POST https://$SCALINGO_API_URL/v1/projects/[:project_id]/transfer_invitations/[:id]/decline` +`POST https://$SCALINGO_API_URL/v1/projects/[:project_id]/transfer_invitations/[:id]/cancel` -The invited collaborator can decline a project transfer invitation. +The project's owner can cancel a project transfer invitation. ||| col ||| @@ -582,7 +559,7 @@ Example request ```shell curl -H "Accept: application/json" -H "Content-Type: application/json" \ -H "Authorization: Bearer $BEARER_TOKEN" \ - -X POST https://$SCALINGO_API_URL/v1/projects/pr-82a3cac5-9b25-473e-b33d-6272b87e636f/transfer_invitations/tin-01234567-89ab-cdef-0123-456789abcdef/decline + -X POST https://$SCALINGO_API_URL/v1/projects/pr-82a3cac5-9b25-473e-b33d-6272b87e636f/transfer_invitations/tin-01234567-89ab-cdef-0123-456789abcdef/cancel ``` Returns 200 OK @@ -592,18 +569,11 @@ Returns 200 OK "transfer_invitation": { "id": "tin-01234567-89ab-cdef-0123-456789abcdef", "project_id": "pr-82a3cac5-9b25-473e-b33d-6272b87e636f", - "invited_user": { - "id": "54100245736f7563d5000000", - "username": "alice", - "email": "alice@example.com" - }, - "inviter": { - "id": "54100245736f7563d5000000", - "username": "john", - "email": "user@example.com" - }, - "status": "declined", - "status_reason": "Declined by invited collaborator", + "invited_user_id": "54100245736f7563d5000000", + "invited_user_name": "alice", + "inviter_user_id": "54100245736f7563d5000000", + "status": "canceled", + "status_reason": "", "expires_at": "2014-09-13T10:17:52.690+02:00", "created_at": "2014-09-10T10:17:52.690+02:00", "updated_at": "2014-09-10T11:00:00.000+02:00"