Submitting Progress Updates

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: On Track, Off Track, At Risk, Achieved, Not Achieved, Canceled, Not Started.

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
  • Fields must use the names exactly: externalId, status, metricValue, asOfDate, comment.
  • Only include comment if you have one.
  • Use valid JSON array syntax.
  • Include the JSON data in the request body.
CSV
  • The default order of the columns in the CSV format is: External ID, Status, Metric Value, As Of Date, Comment (if including comments). Note that these column names are slightly different than the JSON field names.
  • Column headers are optional. If not included, the columns in the CSV must match the default order listed above.
  • If column headers are included, the columns can be in any order.
  • Do not include empty rows.

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-updates

Authorization 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" }