You can publish progress updates for plan items using the AchieveIt REST API. Updates are accepted in JSON or CSV formats. This article describes required fields, how to submit updates, and how to check processing status.
Data Format & Required Fields
You can submit multiple progress updates in each request. Each progress update record must include the following fields.
| Field Name | Required? | Notes |
|---|---|---|
externalID |
Yes | The unique identifier for the plan item in AchieveIt. You can get this using the “Export External IDs” option on the Plan level item for any plan you're an admin of. |
status |
Yes |
Must be one of AchieveIt’s defined statuses. Capitalization doesn’t matter but spelling must match exactly. Possible values: |
metricValue |
Yes (if the item has a metric) | Numeric value with no signs. Represent percentages in decimal format (e.g. 0.2 for 20%). |
asOfDate |
Yes |
Date for the progress update. The date can be formatted in any ISO-8601 compliant date format (e.g. YYYY-MM-DD). Only the date portion is used; any time component is ignored.
|
comment |
No | Optional comment associated with the progress update. Omit if you don't want to include a comment. |
JSON vs CSV Differences
| Format | What to watch out for |
|---|---|
| JSON |
|
| CSV |
|
Example Data
JSON Example
[
{
"externalId": "ce0eced5-b1b9-4504-8ba9-87a476bb0f87",
"status": "On Track",
"metricValue": 0.54,
"asOfDate": "2025-07-03",
"comment": "comment text goes here"
},
{
"externalId": "28e4c9a0-3840-4457-ade8-91e322eb84ea",
"status": "Achieved",
"metricValue": 0.90,
"asOfDate": "2025-08-15"
}
]CSV Example
External ID,Status,Metric Value,As Of Date,Comment
ce0eced5-b1b9-4504-8ba9-87a476bb0f87,On Track,0.54,2025-07-03,"comment text goes here"
28e4c9a0-3840-4457-ade8-91e322eb84ea,Achieved,0.90,2025-08-15,(Download full CSV example file: example-upload-progress-update-file.csv)
Submitting Updates
Enpoint URL
Make an HTTP POST request to the following endpoint:
https://api.achieveit.com/imports/progress-updatesAuthorization Header
Include your API key as part of an authorization header. The API key must be associated with a user that has admin access to all the plan items that you are updating.
Authorization: API-KEY <YOUR_API_KEY>Body Content
Submit your progress update data either directly in the request body or as a file attached to the body (using --data-binary or equivalent). You can submit JSON or CSV formats through either method.
Example Requests
CSV file using cURL in Bash:
// Bash
curl -L -XPOST \
-H "Authorization: API-KEY 12004478285f4f4eb21cd25e62ba5eb7" \
-H "Content-Type: text/csv" \
--data-binary "@my_updates.csv" \
https://api.achieveit.com/imports/progress-updates
CSV file using PowerShell in Bash:
// PowerShell
Invoke-RestMethod -Uri "https://api.achieveit.com/imports/progress-updates" `
-Method Post `
-Headers @{
"Authorization" = "API-KEY 12004478285f4f4eb21cd25e62ba5eb7"
"Content-Type" = "text/csv"
} `
-InFile "C:\path\to\my_updates.csv" `
-ContentType "application/octet-stream"
JSON object using cURL in Bash:
// Bash
curl -X POST "https://api.achieveit.com/imports/progress-updates" \
-H "Authorization: API-KEY 12004478285f4f4eb21cd25e62ba5eb7" \
-H "Content-Type: application/json" \
-d '[
{
"externalId": "12345",
"status": "On Track",
"metricValue": 0.54,
"asOfDate": "2025-09-18",
"comment": "Your comment text"
},
{
"externalId": "67890",
"status": "Achieved",
"metricValue": 1.0,
"asOfDate": "2025-09-18"
}
]'
JSON object using PowerShell in Bash:
// PowerShell
# Define JSON payload
$json = @'
[
{
"externalId": "12345",
"status": "On Track",
"metricValue": 0.54,
"asOfDate": "2025-09-18",
"comment": "Your comment text"
},
{
"externalId": "67890",
"status": "Achieved",
"metricValue": 1.0,
"asOfDate": "2025-09-18"
}
]
'@
# Send POST request
Invoke-RestMethod `
-Uri "https://api.achieveit.com/imports/progress-updates" `
-Method Post `
-Headers @{ "Authorization" = "API-KEY 12004478285f4f4eb21cd25e62ba5eb7" } `
-Body $json `
-ContentType "application/json"
Initial Response
AchieveIt processes submissions to this endpoint in two stages. First, the system validates the data for correct format and required fields, returning either a success or failure response. If validation succeeds, the data is queued for import into your plan items.
Success Response
If validation passes, the API returns HTTP 200 OK with a jobId in the JSON body. You can use this jobId to check the processing status. The response also contains various record counts for the imported data.
{
"jobId": "4272fcb1-9794-41bb-8281-80eaa9bef38b",
"totalRecords": 10,
"errorRecords": 0,
"validRecords": 10
}Failure Response
If validation fails (e.g., due to formatting issues or invalid field values), the API returns HTTP 400 Bad Request with a JSON payload detailing the errors.
- AchieveIt validates every record in the submission and will respond with a comprehensive list of all errors. There may be more than one error for each record in the submission.
- If there are any errors in the data, AchieveIt will not import ANY of the progress update records in the submission. You will need to correct the errors and resubmit the entire data set.
{
"jobId": "2bf2dda7-2aa4-4345-b6a8-8070d6ceec39",
"totalRecords": 5,
"errorRecords": 2,
"validRecords": 3,
"errors": [
{
"position": 0,
"externalId": "AA234",
"errors": [
{
"field": "ExternalId",
"value": "AA234",
"message": "External ID is invalid or its associated plan item has been deleted."
},
{
"field": "Status",
"value": "TestStatus",
"message": "Status is invalid."
}
]
},
{
"position": 1,
"externalId": "28e4c9a0-3840-4457-ade8-91e322eb84ea",
"errors": [
{
"field": "asOfDate",
"value": "",
"message": "AsOfDate is required."
}
]
}
]
}Checking Processing Status
Once your submission passes the first validation stage, you can check the status of the import process by making an HTTP GET request to the status endpoint corresponding using your jobId. Make sure to include the API-KEY in the Authorization header.
https://api.achieveit.com/imports/status/<jobId>
The API will respond with a JSON message indicating the state that your request is currently in.
{
"jobId": "2bf2dda7-2aa4-4345-b6a8-8070d6ceec39",
"created": "2025-08-25T19:01:21.9329991",
"status": "Processing",
"errors": [...]
}
The Status field can be one of the following values:
-
Queued- Request has been received and is awaiting processing. -
Processing- Request is being processed. -
Completed- Request has processed successfully, and the the updates have been added to the plan items. -
Failed- Request failed validation. The JSON response will include the validation errors.
Error Cases
The validation at this stage works the same as it does in the initial submission stage. If there is a validation failure for any record, none of the data will be imported.
Example Requests
// Bash
curl -i -XGET \
-H "Authorization: API-KEY 12004478285f4f4eb21cd25e62ba5eb7" \
https://api.achieveit.com/imports/status/2bf2dda7-2aa4-4345-b6a8-8070d6ceec39
// PowerShell
Invoke-RestMethod -Uri "https://api.achieveit.com/imports/status/2bf2dda7-2aa4-4345-b6a8-8070d6ceec39" `
-Method Get `
-Headers @{ "Authorization" = "API-KEY 12004478285f4f4eb21cd25e62ba5eb7" }