Creating your own approval application
Read time: 6 minutes
Last edited: Oct 30, 2024
Overview
This topic describes how to create your own approval application, which serves as an intermediary between LaunchDarkly approvals and your workflow management application. This is the first step required in building a custom approvals integration. Only customers with complex workflow management or approval systems in third-party applications that LaunchDarkly does not integrate with directly are likely to need a custom approvals integration.
Create your own approval application
To use custom approvals, you must create and host your own approval application. This might be a standalone application, or it might be a middleware application that you deploy between LaunchDarkly and your existing third-party workflow management system, such as ServiceNow. If you are working with a third-party workflow management system, then your application should transform outgoing LaunchDarkly requests related to approval flows and forward them to the approval service of your choice.
Authentication
LaunchDarkly will send requests to your application using the request header "Authorization": "Bearer <API_KEY>"
. LaunchDarkly will save an encrypted version of this key and use it to authenticate all outgoing requests from our service to yours.
You specify both the API_KEY
and the BASE_URL
that LaunchDarkly should use when you define the integration configuration for custom approvals integration. LaunchDarkly saves this information as part of the integration configuration, and uses it only to construct outgoing requests from LaunchDarkly to your custom application.
Requests from LaunchDarkly to your application
LaunchDarkly will make the following requests to your application:
-
creationRequest
: LaunchDarkly sends this upon approval request creation. The input from theadditionalApprovalFormVariables
defined on your custom approvals integration configuration will be merged into the body of this request. -
statusRequest
: LaunchDarkly sends this every five minutes, or whenever the approval request page in LaunchDarkly is refreshed. -
postApplyRequest
: LaunchDarkly sends this after a LaunchDarkly approval request has been applied. -
deletionRequest
: LaunchDarkly sends this whenever a LaunchDarkly approval request is deleted. -
memberListRequest
: (optional) LaunchDarkly sends this upon setup, and every four hours thereafter, to associate LaunchDarkly member resources with corresponding external user objects.
The custom-approvals
integration manifest defines generic versions of these requests. The following sections describe the requests in more detail.
creationRequest and required response
Here's the specification for the creationRequest
that LaunchDarkly sends:
Request element | Description |
---|---|
Method | POST |
URL | <BASE_URL>/api/approvals
|
Headers | { "Content-Type": "application/json", "Authorization": "Bearer <API_KEY>"}
|
Request body (sample) | { "links": { "href":"https://app.launchdarkly.com/projects/default/flags/sample-flag/approvals/66a8e20c0754610fae1fcf5d" }, "approvalId":"66a8e20c0754610fae1fcf5d", "details":"Created approval request: this is an example comment Requested change is: Turn on the flag", "project": { "name":"Default Project", "key":"default", "tags":["sample", "sample-2"] }, "environment": { "name":"Sample Environment", "key":"sample-environment", "tags":["sample"] }, "flag": { "name":"Sample Flag", "key":"sample-flag", "tags":["sample"] }, "requestedBy": { "id":"6488a76452a4d51480ec2b4e", "email":"jdoe@example.com" }, "shortDescription":"Jane Doe requested approval for changes to the flag Sample Flag in 'Sample Environment'", "timestamp": "2024-08-31 10:11:36", "comment": "this is an example comment", "approvalFormVariables": { "yourCustomVariable1": "blue", "yourCustomVariable2": "green" } } |
LaunchDarkly expects the following response from your application:
Response element | Description |
---|---|
HTTP Code | 2xx |
Body | { "id": <APPROVAL_ID>, // as taken from the request from LD "result": { "status": "approved", "displayStatus": "Approved" } } LaunchDarkly considers status values of approved or declined as approved or declined requests. The displayStatus can be any string and is displayed in the LaunchDarkly user interface. |
statusRequest and required response
Here's the specification for the statusRequest
that LaunchDarkly sends:
Request element | Description |
---|---|
Method | GET |
URL | <BASE_URL>/api/approvals/<APPROVAL_ID>/status
|
Headers | { "Authorization": "Bearer <API_KEY>"}
|
Request body (sample) | The request asks for the status of the APPROVAL_ID. The request body is empty. |
LaunchDarkly expects the following response from your application:
Response element | Description |
---|---|
HTTP Code | 2xx |
Body | { "id": <APPROVAL_ID>, "result": { "status": "pending", "displayStatus": "Pending review" } } LaunchDarkly considers status values of approved or declined as approved or declined requests. The displayStatus can be any string and is displayed in the LaunchDarkly user interface. |
postApplyRequest and required response
Here's the specification for the postApplyRequest
that LaunchDarkly will send:
Request element | Description |
---|---|
Method | POST |
URL | <BASE_URL>/api/approvals/<APPROVAL_ID>/applied
|
Headers | { "Content-Type": "application/json", "Authorization": "Bearer <API_KEY>"}
|
Request body (sample) | The request indicates that APPROVAL_ID has been applied in LaunchDarkly. The request body is empty. |
LaunchDarkly expects the following response from your application:
Response element | Description |
---|---|
HTTP Code | 2xx |
Body | { "id": <APPROVAL_ID>, "result": { "status": "declined", "displayStatus": "declined" } } LaunchDarkly considers status values of approved or declined as approved or declined requests. The displayStatus can be any string and is displayed in the LaunchDarkly user interface. |
deletionRequest and required response
Here's the specification for the deletionRequest
that LaunchDarkly will send:
Request element | Description |
---|---|
Method | POST |
URL | <BASE_URL>/api/approvals/<APPROVAL_ID>/cancel
|
Headers | { "Content-Type": "application/json", "Authorization": "Bearer <API_KEY>"}
|
Request body (sample) | The request indicates that APPROVAL_ID has been deleted in LaunchDarkly. The request body is empty. |
LaunchDarkly expects the following response from your application:
Response element | Description |
---|---|
HTTP Code | 2xx |
Body | { "id": <APPROVAL_ID>, "result": { "status": "cancelled", "displayStatus": "Cancelled" } } LaunchDarkly considers status values of approved or declined as approved or declined requests. The displayStatus can be any string and is displayed in the LaunchDarkly user interface. |
memberListRequest and optional response
Here's the specification for the memberListRequest
that LaunchDarkly will send:
Request element | Description |
---|---|
Method | GET |
URL | <BASE_URL>/api/members |
Headers | { "Authorization": "Bearer <API_KEY>"}
|
Request body (sample) | The request asks for LaunchDarkly members. The request body is empty. |
Responding to this request is optional. If implemented, LaunchDarkly expects the following response from your application:
Response element | Description |
---|---|
HTTP Code | 2xx |
Body | { "result": [ { "name": "Jane Doe", "email": "jdoe@example.com" }, { "name": "Sandy Smith", "email": "ssmith@example.com" }, ... etc ] } |