HTTP Endpoints
Use HTTP endpoints to define custom API endpoints for Jira. They enable you to integrate Jira with external systems by exposing custom logic over HTTP or by consuming external services from within Jira. You could use an HTTP endpoint to:
Provide an API that returns specific work item details Expose a custom HTTP endpoint that returns exactly the work item fields and data you need. Use this to power internal tools, dashboards, or integrations without giving direct access to Jira's full API.
Trigger Jira updates (such as transitions or field changes) based on external events Define an HTTP endpoint that, when called by an external system, performs actions in Jira, such as transitioning a work item, updating fields, or adding comments. Use this to keep Jira in sync with CI/CD pipelines, monitoring tools, or other business systems.
Aggregate and expose data from Jira and other systems in a single response Create an HTTP endpoint that calls Jira and other external APIs, combines the results, and returns a unified response. Use this to provide a single, simplified data source for reporting, dashboards, or downstream integrations.
HTTP endpoints are exposed as URLs that external systems can call, or that you can invoke from your own scripts and automations. All endpoints are mounted at /api/** and support GET, POST, PUT, DELETE, and PATCH.
Request object
When an HTTP endpoint is called, your script receives an ApiRequest object as its first argument. This object contains everything you need to handle the request; the HTTP method, any path or query parameters, headers, and the request body.
typescriptimport type { ApiRequest, ApiResponse } from "@avst-sr/types/api-endpoints";
| Field | Type | Description |
|---|---|---|
url | string | The request URL (after the /api prefix) |
method | string | HTTP method: GET, POST, PUT, DELETE, PATCH |
pathParams | Record<string, string | undefined> | Named parameters from the path pattern |
queryParams | Record<string, string[]> | Query string parameters |
headers | Record<string, string[]> | Request headers |
body | string (optional) | Request body (for POST, PUT, PATCH) |
A common pattern is to destructure the fields you need at the top of your script:
typescriptconst { method, pathParams, queryParams, body } = request;
Response object
Your script must return an ApiResponse object. This tells ScriptRunner what HTTP status code and body to send back to the caller.
typescriptinterface ApiResponse { statusCode: number body: string }
statusCode— a standard HTTP status code, such as200for success,201for created,400for a bad request, or404for not found. Use appropriate codes to make your endpoint behave like a well-formed API.body— must always be a string. If you want to return a JSON object, serialise it first withJSON.stringify().
A minimal valid response looks as follows:
typescriptreturn { statusCode: 200, body: JSON.stringify({ message: "Success" }), };
Always return an ApiResponse from every code path in your script, including error cases. If your script throws an unhandled error, the endpoint will return a 500 response.
Path patterns
The path you enter when creating an endpoint defines the URL route it responds to. Paths can include named parameters and wildcards, which are automatically extracted and made available in pathParams inside your script.
There are two types of dynamic segments:
- Named parameters (
:paramName) — match a single path segment and capture its value. For example,:issueKeyin/issues/:issueKey/linkscaptures the issue key from the URL. - Wildcards (
:paramName*) — match one or more path segments and capture them as a single string. For example,:path*in/search/:path*captures everything after/search/.
| Pattern | Matches | pathParams |
|---|---|---|
/issues/:issueKey/links | /issues/ISSUE-42/links | { issueKey: "ISSUE-42" } |
/issues/:issueKey/links/:linkId | /issues/ISSUE-42/links/123 | { issueKey: "ISSUE-42", linkId: "123" } |
/projects/:projectKey/issues | /projects/PROJ/issues | { projectKey: "PROJ" } |
/repos/:owner/:repo/issues | /repos/atlassian/AUI/issues | { owner: "atlassian", repo: "AUI" } |
/search/:path* | /search/a/b/c | { path: "a/b/c" } |
Output and logging
When you run a script, the output panel shows:
- Anything logged with
console.log(...) - The final value returned by your script with
return
Use console.log(...) for messages, intermediate values, or debugging, and include a return statement for the main result you want to display. Each time you select Run, the output panel is cleared and refreshed with the latest logs and return value.
Execution history
Saved HTTP endpoints keep a full execution history (under Output), so you can review when they were run, and what the output was, making it easier to audit and troubleshoot.
Calling an endpoint externally
Once your endpoint is saved, any external system or tool can call it over HTTP using a bearer token for authentication.
Finding your endpoint URL
Your endpoint's full URL is displayed in the editor, under the path field, with a copy button. Endpoint URLs follow one of these patterns:
typescripthttps://<site-name>.atlassian.net/gateway/api/svc/jira/apps/<appId>_<envId>/api/<path> https://api.atlassian.com/svc/jira/<cloudId>/apps/<appId>_<envId>/api/<path>
Both resolve to the same handler. We recommend you use whichever fits your integration.
Authentication
HTTP endpoints use OAuth 2.0 bearer token authentication. Include your access token in the Authorization header of every request:
typescriptAuthorization: Bearer <access_token>
For detailed steps on obtaining a token and sending authenticated requests, see the Atlassian documentation Access REST APIs exposed by a Forge app.
Required scopes
The calling service must be granted the correct scopes before it can invoke your endpoint:
| Integration type | Required scopes |
|---|---|
| Server-to-server (3LO) | invoke:user-script:custom and read:forge-app:jira |
| Other | invoke:user-script:custom |
If the calling service is missing the invoke:user-script:custom scope, requests will be rejected with a 403 Forbidden response.
Create an HTTP endpoint
Follow these steps to create a new HTTP endpoint:
- In Jira administration, select Marketplace apps.
- Under Apps, select ScriptRunner.js.
- Select HTTP endpoint.
- Select Create.
- Enter a Name and, optionally, a Description.
- Enter a Path for the endpoint. The path defines the URL route your endpoint will be accessible at, and supports named parameters and wildcards. For example,
/issues/:issueKey/linkscaptures the issue key as a path parameter. See Path patterns for the full syntax reference. - Choose who you want the script to Run as. Select whether the HTTP endpoint runs with ScriptRunner app permissions or as a specific user.
- Write your script.
To help you write scripts, you can use the HTTP endpoint examples, use HAPI, or select Example scripts directly in the script editor.
- Optional: Select Run to run your script and make sure it works as expected.
- If the script performs updates (for example, creates or edits work items), those changes are applied to your Jira instance.
- Test in a non‑production environment first.
- Use the Output panel to review results and troubleshoot any errors.
- Select Save.
Edit an HTTP endpoint
Use these steps to modify an existing HTTP endpoint:
- In Jira administration, select Marketplace apps.
- Under Apps, select ScriptRunner.js.
- Select HTTP endpoints.
- Find your HTTP endpoint in the list and select Edit.
- Modify the HTTP endpoint as needed.
- Optional: Select Run to run your script and make sure it works as expected.
- If the script performs updates (for example, creates or edits work items), those changes are applied to your Jira instance.
- Test in a non‑production environment first.
- Use the Output panel to review results and troubleshoot any errors.
- Select Save.
Enable and disable an HTTP endpoint
To enable or disable your HTTP endpoint:
- In Jira administration, select Marketplace apps.
- Under Apps, select ScriptRunner.js.
- In ScriptRunner, select HTTP endpoints.
- Locate the HTTP endpoint you want to enable or disable.
- Open the ellipsis (…) menu for that HTTP endpoint and select Disable or Enable.
Delete an HTTP endpoint
Remove HTTP endpoints you no longer need to keep your list organized and reduce clutter. When you delete an HTTP endpoint, it’s removed from your active HTTP endpoints list and will no longer be callable, but it isn’t permanently removed. You can still access and restore it from ScriptRunner if needed.
To delete an HTTP endpoint:
- In Jira administration, select Marketplace apps.
- Under Apps, select ScriptRunner.js.
- Select HTTP endpoints.
- Find the HTTP endpoint you want to remove.
- Open the ellipsis (…) menu for that HTTP endpoint.
- Select Delete.
- When prompted, confirm that you want to delete the HTTP endpoint.
Deleted HTTP endpoints can be restored, including their execution history.
Restore a deleted HTTP endpoint
You can restore deleted HTTP endpoints along with their execution history. To restore a deleted HTTP endpoint:
- In Jira administration, select Marketplace apps.
- Under Apps, select ScriptRunner.js.
- Select HTTP endpoints.
- Use the filter and select Deleted to view deleted HTTP endpoints.
- Find the HTTP endpoint you want to restore.
- Open the ellipsis (…) menu for that HTTP endpoint.
- Select Restore. The HTTP endpoint and its full execution history will be available again in your active HTTP endpoints list.