Use this guide to diagnose Support Time Contract Management REST API errors, plan imports and handle asynchronous calculations.
Every endpoint needs an active app license, App REST APIs enabled on the site, an edition that allows the API, and the matching app scope plus read:forge-app:jira. Advanced has API access; Standard has access only when a rollout has explicitly enabled it for your site.
App error format
{
"error": {
"code": "VALIDATION",
"message": "Contract validation failed",
"details": {
"errors": [
"endDate before startDate"
]
}
},
"inv": null
}
|
Field |
Meaning |
|---|---|
|
error.code |
Stable machine-readable code. Branch on it rather than message. |
|
error.message |
Human-readable explanation; may change and is not localized. Server-side 5xx app messages are generic. |
|
error.details |
Optional details: VALIDATION may include errors or reason; EDITION_REQUIRED includes edition; LICENSE_INACTIVE includes active. |
|
inv |
Reserved support invocation ID; currently always null. |
Atlassian gateway errors can have a different body and do not necessarily contain the app’s error.code.
Status codes and handling
|
HTTP status |
Code / source |
Meaning and action |
|---|---|---|
|
400 |
VALIDATION / app |
Malformed JSON, invalid fields, limit violation or invalid scope JQL. Correct the request using message/details; do not retry it unchanged. |
|
401 |
Gateway |
Missing, invalid or expired token. Send a valid Bearer token; refresh when expired. |
|
403 |
LICENSE_INACTIVE / app |
Restore or renew the app subscription before retrying. |
|
403 |
EDITION_REQUIRED / app |
Current edition lacks API access. Upgrade to Advanced or contact VIEW26 about rollout availability for your Standard site. details.edition identifies the current edition. |
|
403 |
Gateway |
App REST APIs are disabled on the site or the token lacks a required scope. Check admin settings and OAuth consent. |
|
404 |
NOT_FOUND / app |
Unknown contract/import batch. Verify the app ID, contract ID or batch ID as applicable. |
|
404 |
Gateway: No matching API route found |
Check method, base URL and path, including /v1. |
|
413 |
Gateway |
Import body too large. Split into smaller batches, each at most 200 contracts. |
|
429 |
Gateway |
Platform rate limit. Back off exponentially and honor Retry-After when present. |
|
500 |
INTERNAL / app |
Unexpected error. Retry with backoff; contact support if persistent. |
|
5xx |
Gateway |
Transient platform/upstream error. Retry with backoff. |
Retry behavior
-
Use externalId for POST create requests and retain it on retries; without it a retry can create a duplicate. Import idempotency is per row and every row requires externalId.
-
Repeating PUT reaches the same end state. Repeating DELETE also leaves the contract deleted, but the second call returns 404 NOT_FOUND.
-
A 202 import response can include rejected rows. Inspect them, fix the validation failures and resubmit those rows.
-
Back off after 429 or transient 5xx errors. Do not repeatedly retry an unchanged validation, license or edition error.
Limits
|
Limit |
Value / guidance |
|---|---|
|
Contracts per import |
1–200; submit larger migrations as sequential batches. |
|
List page size |
1–100; default 50. |
|
Contract name |
Non-empty; no maximum enforced by the API. |
|
contractedHours / consumedHours |
Non-negative decimal hours. |
|
Access token |
1 hour; reuse it across requests. |
|
Refresh token |
Rotates on every use; expires after 90 days unused. |
|
Rate limits |
Atlassian platform limits apply. The supplied v1 reference does not specify a numeric request quota. Honor 429 and Retry-After. |
|
Contracts per site |
The current app stores contracts in one Forge KVS record (240 KB maximum). Contact VIEW26 before importing more than a few hundred contracts to a site. |
Calculation and freshness
Create, update and read calls usually return in 1–4 seconds. Hours are calculated asynchronously: small scopes can complete in seconds; scopes matching thousands of issues can take minutes. These are typical timings, not guarantees.
-
A contract can be read as soon as creation completes; newly created or imported contracts report CALCULATING while hours are processed.
-
Poll Get a contract or Get import status. Wait for computation before relying on loggedHours, remainingHours or final status.
-
A finished import can include FAILED contracts. Check failed as well as isFinished.
-
If a batch contract is deleted before calculation finishes, isFinished can remain false. Reconcile remaining accepted IDs against List contracts.
-
Later Jira worklog changes are reflected over time by the app’s own sync.
Troubleshooting
|
Symptom |
Cause |
Fix |
|---|---|---|
|
401 Unauthorized |
Missing, expired or malformed token. |
Send Authorization: Bearer <token>; renew expired tokens. |
|
403 REST APIs are not allowed for appId=…, envId=… |
API is disabled for this app/site. |
Ask a site or organization admin to enable App REST APIs in Connected apps. |
|
403 Missing required scopes for path=…, method=… |
Missing route scope/product scope, or sns was omitted from authorization URL. |
Add the required scopes including read:forge-app:jira; obtain consent again with the console-generated URL and preserved sns. |
|
403 LICENSE_INACTIVE |
Inactive app license. |
Restore or renew the Marketplace subscription. |
|
403 EDITION_REQUIRED |
Edition does not allow API access. |
Upgrade to Advanced or contact VIEW26 about enabling the rollout on your Standard site. |
|
404 No matching API route found |
Incorrect method/path/base URL. |
Compare against the endpoint list and include /v1. |
|
Contract remains CALCULATING |
Large issue scope or Jira rate limiting. |
Allow time for large calculations. If it becomes FAILED, narrow/fix scope and re-save with PUT. |
|
Contract is FAILED |
Computation hit internal audit-size limits or persistent upstream errors. |
Narrow scope to fewer issues and re-save with PUT; contact support if persistent. |
|
Imported hours are too low |
Historical worklogs were not migrated or started dates are outside the contract window. |
Migrate worklogs preserving started dates, or use consumedHours for the historical opening balance. Do not count the same time in both. |
Need help?
Contact VIEW26 with your site URL, endpoint and method, HTTP status and error code, and affected contract or batch IDs. Omit access tokens and client secrets.
Related documentation