REST APIs

Overview

The system provides a Representational State Transfer (REST) API to work with key records.

REST provides a consistent URI for access and manipulation of a specific data record. Under REST, a single URI represents a data record, and the HTTP verb controls the manipulation according to the following table:

Method
Description
Example

GET

Returns a collection of items based on a filter

GET /api/json/item?...

POST

Creates a new item

POST /api/json/item

GET

Returns a single item

GET /api/json/item/id/1

PUT

Updates a single item

PUT /api/json/item/id/1

Collections

The Crisisworks REST API returns either returns a single object or a collection of objects, based on its invocation.

Collections contain the following JSON structure:

{
    "models": {
        "1": { ... }
        "2": { ... }
        "3": { ... }
        "4": { ... }
        "5": { ... }
    },
    "count": 5,
    "total": "22608"
}

In the collection structure:

  • models contains an array of individual model structures,

  • count contains the number of returned objects, and

  • total contains the total set (this will be different if you call the API with a limit and/or offset parameter to paginate the set).

Records

Use the GET method and supply an id parameter to fetch a single record.

GET https://{{host}}/api/json/item/id/1
Authorization: Bearer {{token}}
X-Site: {{site}}

Example:

GET https://{{host}}/api/json/item/id/1
Accept: application/json
Content-Type: application/json;charset=UTF-8
Authorization: Bearer {{token}}
X-Site: {{site}}
{
    "id": "1",
    "eventId": "234",
    "due": null,
    "isSensitive": false,
    "itemSchemaName": "default",
    "userId": "myuser",
    "status": "10",
    "templateName": null,
    "costEstimate": "10000.00",
    "type": "recoveryInfrastructure",
    "title": "Small Rd (ACCESS RURAL) ",
    "address": "Small Rd (ACCESS RURAL) ",
    "assetId": "72784",
    "assignee": 0,
    "_canEdit": true,
    "dateCreated": "2016-09-29T15:07:27+10:00",
    "dateUpdated": "2016-09-29T15:07:27+10:00",
    "isTemplate": false,
    "tags": "",
    "descriptionPhotos": [],
    "scopePhotos": [],
    "contractors": [],
    "description": null,
    "scope": null,
    "costActual": "0",
    "priority": "2",
    "riskLevel": null
}

The contents of the record structure depends on the type of content being retrieved.

If the record does not exist or is not accessible, the following is returned.

{
  "status": 404,
  "message": "Not found"
}

Working with REST collections

Fetching a collection of records

Fetching a collection of RESTful objects is achieved by calling its base URL without an identifier. e.g.

GET https://{{host}}/api/json/item?{{filter}}
Accept: application/json
Content-Type: application/json;charset=UTF-8
Authorization: Bearer {{token}}
X-Site: {{site}}

The {{filter}} is a standard GET parameter list with the following parameters.

Specifying the register

For item collections you must specify the type of register:

registerId=contact

Filtering

Filters can be provided using CQL.

Like all GET requests, the values must be URL encoded.

For example, to filter the CQL query

is:active status:[requested,assigned]

Your filter will look like:

cql=is%3Aactive%20status%3A%5Brequested%2Cassigned%5D

Your language will have its own way to URL Encode variables.

Ordering

Collections can be ordered by a limited number of columns, with the most common being id, dateCreated and dateModified.

orderBy=dateCreated&orderDirection=ASC

Pagination

Optional pagination is controlled via limit and offset.

limit=5&offset=50

Each result will return the count in the result, and the total records:

{
  "models": [...],
  "count": 100,
  "total": "212",
}

Example: get results 50-55 of recoveryInfrastructure

https://{{host}}/api/json/item?limit=5&offset=50&type=recoveryInfrastructure
Accept: application/json
Content-Type: application/json;charset=UTF-8
Authorization: Bearer {{token}}
X-Site: {{site}}
{
    "models": {
        "10744": {
            ...
        },
        "10755": {
            ...
        },
        "10756": {
            ...
        },
        "10757": {
            ...
        },
        "10759": {
            ...
        }
    },
    "count": 5,
    "total": "312",
}

Searching and filtering records

You can use CQL to search and filter your records.

  • See our user guide for details

  • A data dictionary exists for each register, and you will find the link in the UI under the search box.

A full example in CQL for Crisisworks might be this — the following returns active records in event 22 updated in the last 30 days:

is:active event:22 dateUpdated:>now-30d

Like all GET parameters, you must encode these values using your language's URL Encode function.

To run CQL in the REST API, you must url encode it and use a parameter called cql.

https://{{host}}/api/json/item?type=recoveryCase&cql=is%3Aactive+event%3A22+dateUpdated%3A%3Enow-30d'
Accept: application/json
Content-Type: application/json;charset=UTF-8
Authorization: Bearer {{token}}
X-Site: {{site}}

Working with REST Records

Submitting new records

New records can be submitted using POST.

  • JSON Input follows the same structure as that returned from the GET API.

  • The JSON response reflects the final values of the record after being saved.

  • Possible error codes include 40x and 50x status codes. All have a human-readable message, and use http codes so you can follow that spec to know whether it's a temporary or permanent error.

POST https://{{host}}/api/json/item
Accept: application/json
Content-Type: application/json;charset=UTF-8
Authorization: Bearer {{token}}
X-Site: {{site}}

{
    "title": "Test submission via API",
    "requestor": "Scott Davey",
    "registerId": "recoveryInfrastructure",
    "field...": "value..."
}

The API will respond with the saved data.

{
    "id": 12345,
    "registerId": "recoveryInfrastructure",
    "title": "Test submission via API",
    "requestor": "Scott Davey",
    "field...": "value..."
}

The fields and values are defined in the module guide.

Updating existing records

To update an existing record, use PUT or PATCH.

PUT and PATCH work similarly, where:

  • PUT expecting a full record, while

  • PATCH expects a change-set.

Tip: When using PUT, missing data will be treated as if the value is set to null, and this will overwrite existing values at the server.

Possible error codes include 40x and 50x codes, as usual.

PUT https://{{host}}/api/json/item/id/123
Accept: application/json
Content-Type: application/json;charset=UTF-8
Authorization: Bearer {{token}}
X-Site: {{site}}

{
    "id": 123,
    "registerId": "recoveryInfrastructure",
    "title": "Test submission via API",
    "requestor": "Scott Davey",
    "field...": "value..."
}

The API will respond with the saved data.

{
    "id": 123,
    "registerId": "recoveryInfrastructure",
    "title": "Test submission via API",
    "requestor": "Scott Davey",
    "field...": "value..."
}

Deleting records

Records in Crisisworks cannot be deleted. Instead, set the status to an inactive status.

Consult the relevant module reference guide for more information.

REST Commands

Asset

The asset REST command searches and returns assets in Crisisworks.

To search:

GET /api/json/asset?{{parameters}}

To return a specific record by its ID:

GET /api/json/asset/id/{{id}}

GET Parameters

Key(s)
Type
Details

limit

Number

When paginating, how many records to return

offset

Number

When paginating, which record to start from

id

Integer

Returns a record of a specific ID

fulltext

String

Returns records containing the supplied text, as analysed by the full-text search parser.

soundex

String

Returns records where the title sounds like the supplied string Aliases: name

active

Boolean

Returns only active (or inactive) records based on supplied value

type

String

Returns records matching the given asset type. For a list of asset types, see the asset-type API command.

code

String

Returns records matching the given asset code

isImpacted

Boolean

Returns records that have an active register item record in Crisisworks

latitude

longitude range

Number

Returns assets near the provided geospatial location.

Example

Return 1 matching asset.

GET https://{{host}}/api/json/asset?limit=1
Authorization: Bearer {{token}}
X-Site: {{site}}

Result:

{
    "models": {
        "1": {
            "id": "1",
            "name": "TP827623",
            "code": "100044818",
            "type": "Asset_Property",
            "friendlyType": "Property",
            "geo": {
                "points": [],
                "polygons": [
                    {
                        "points": [
                            {
                                "longitude": "144.01960063",
                                "latitude": "-37.67845485"
                            },
                            {
                                "longitude": "144.01926323",
                                "latitude": "-37.67851867"
                            },
                            {
                                "longitude": "144.01912979",
                                "latitude": "-37.67853825"
                            },
                            {
                                "longitude": "144.01899564",
                                "latitude": "-37.67855447"
                            }
                        ]
                    }
                ],
                "linestrings": []
            },
            "_distance": null,
            "style": "green",
            "_within": false,
            "_order": 1
        }
    },
    "count": 1,
    "total": "22608",
    "updated": "2016-08-03T00:33:44+00:00"
}

Event

This command fetches available events, and allows updating.

Fetch Individual Event

Example

GET /api/json/event/id/123
Authorization: Bearer {{token}}
X-Site: {{site}}

Search Events

Example

GET /api/json/event
Authorization: Bearer {{token}}
X-Site: {{site}}

Parameters

Keys
Type
Details

limit

Number

When paginating, how many records to return

offset

Number

When paginating, which record to start from

id

Number

Search by ID

fulltext

String

Set fulltext_operator to the desired operator if changing from the default

status

String

Search item

active

Boolean

All active statuses

startDateAfter

Date Time String

startDateBefore

Date Time String

tag

String

Search for events containing this tag

isTemplate

Boolean

isGlobal

Boolean

Example: Fetch the most recent event

Request:

GET https://{{host}}/api/json/event?limit=1&order=id&orderDirection=DESC
Authorization: Bearer {{token}}
X-Site: {{site}}

Result:

{
    "models": {
        "1021": {
            "id": "1021",
            "title": "Fire at Broadbeach",
            "description": "",
            "startDate": "2016-08-11T03:58:00+00:00",
            "endDate": null,
            "status": {
                "label": "Open",
                "value": 1,
                "style": "yellow"
            },
            "severity": "2",
            "participants": [
                {
                    "id": "2758",
                    "type": "position",
                    "name": "Archive Officer",
                    "positionId": "81"
                },
                {
                    "id": "2759",
                    "type": "user",
                    "name": "Pete Bool",
                    "userId": "pbool"
                }
            ],
            "userParticipants": [],
            "_isSelectable": true,
            "parentId": "1",
            "_order": 1
        }
    },
    "count": 1,
    "total": "50",
    "updated": null
}

Update Event

PUT https://{{host}}/api/json/event/id/{{id}}
Authorization: Bearer {{token}}
X-Site: {{site}}

{
    "PAYLOAD"
}

Example: Close an event and update its description

PUT https://{{host}}/api/json/event/id/25
Authorization: Bearer {{token}}
X-Site: {{site}}

{
  "id": "25",
  "title": "My Event",
  "description": "This event was closed today",
  "startDate": "2017-01-08T03:00:00+00:00",
  "endDate": "2017-01-08T04:00:00+00:00",
  "status": {
    "label": "Closed",
    "value": -1,
    "style": "grey"
  },
  "severity": "3",
  "participants": [],
  "userParticipants": [],
  "_isSelectable": true,
  "parentId": "1"
}

Register Item

A RESTful command to access and manage register items, which are the primary business object within the system.

GET /api/json/item
POST /api/json/item
GET /api/json/item/id/123
PUT /api/json/item/id/123

GET Parameters

The majority of filtering will use CQL search terms.

Please consult the register guide or contact Datalink's Service Desk for more details.

Keys
Type
Details

limit

Number

When paginating, how many records to return

offset

Number

When paginating, which record to start from

registerId

String

Aliases: type ; Set to the register ID for filtering.

cql

String

Aliases query; Use this for all field-level and full-text querying using the CQL query language.

eventId

String

since

String

Set since_operator to the desired operator if changing from the default

until

String

Set until_operator to the desired operator if changing from the default

isTemplate

String

Filter to include or exclude template items

Example: fetch all active FPN records

Example output of all active FPN items. Note, the first item has an attached asset and shows how the extra fields are returned.

GET https://{{host}}/api/json/item?type=fpn&active=1
Authorization: Bearer {{token}}
X-Site: {{site}}

Response

{
    "models": {
        "14919": {
            "id": "14919",
            "eventId": "1014",
            "due": null,
            "isSensitive": false,
            "itemSchemaName": "moorabool",
            "userId": "pkakris.mb",
            "status": "20",
            "templateName": null,
            "costEstimate": "0.00",
            "type": "fpn",
            "title": null,
            "address": null,
            "assetId": "1345678",
      	    "asset_friendly": "7 TEST STREET 3000",
            "asset_code": "pr_1234567",
            "asset_type": "Asset_Property_Vicmap",
            "asset_extra": {
                "spi": "2\\PS12345",
                "code": "pr_1234567",
                "crefno": "11111",
                "propnum": "22222",
                "fur_desc": null,
                "prop_pfi": "4444444",
                "parcel_pfi": "444444"
            },
            "assignee": "2632",
            "assignee_info": "Pete Kakris",
            "_canEdit": true,
            "dateCreated": "2016-03-03T13:13:33+11:00",
            "dateUpdated": "2016-03-03T13:13:33+11:00",
            "isTemplate": false,
            "tags": "",
            "infringementNumber": null,
            "contractors": [],
            "media": [
                {
                    "id": "602",
                    "uri": "\/api\/binary\/media\/602",
                    "thumbUri": "\/api\/binary\/media\/602?type=thumb",
                    "type": "image\/jpeg",
                    "name": "blob.jpg",
                    "created": "2016-03-03T02:13:22+00:00",
                    "size": "71785"
                }
            ],
            "mergedFile": [],
            "activity": null,
            "cutGrassWeeds10cm": false,
            "removeDebris": false,
            "firebreak10m": false,
            "cutGrassWeeds5cm": false,
            "trimTrees": false,
            "removeFlammable": false,
            "notes": null,
            "dateNewFromWeb": null,
            "dateNewFromMobile": null,
            "date1stInspectionRequired": null,
            "dateHazardExists": "2016-03-03T02:13:33+00:00",
            "dateComplianceInspectionRequired": null,
            "dateRequestCompulsoryClearing": null,
            "datePostClearanceInspectionReview": null,
            "dateHazardCleared": null,
            "dateTemporaryExemptionGranted": null,
            "dateClosed": null,
            "dateNoticeWithdrawn": null,
            "dateFpnSent": null,
            "infringementSentDate": null,
            "_order": 1
        },
        "14968": {
            "id": "14968",
            "eventId": "1014",
            "due": null,
            "isSensitive": false,
            "itemSchemaName": "moorabool",
            "userId": "pkakris.mb",
            "status": "20",
            "templateName": null,
            "costEstimate": "0.00",
            "type": "fpn",
            "title": "PARCEL 45530943",
            "address": "PARCEL 45530943",
            "assetId": "24733",
            "assignee": "2632",
            "assignee_info": "Pete Kakris",
            "_canEdit": true,
            "dateCreated": "2016-06-20T14:06:27+10:00",
            "dateUpdated": "2016-06-20T14:06:27+10:00",
            "isTemplate": false,
            "tags": "",
            "infringementNumber": null,
            "contractors": [],
            "media": [],
            "mergedFile": [],
            "activity": null,
            "cutGrassWeeds10cm": true,
            "removeDebris": false,
            "firebreak10m": false,
            "cutGrassWeeds5cm": false,
            "trimTrees": false,
            "removeFlammable": false,
            "notes": null,
            "dateNewFromWeb": null,
            "dateNewFromMobile": null,
            "date1stInspectionRequired": null,
            "dateHazardExists": "2016-06-20T04:06:27+00:00",
            "dateComplianceInspectionRequired": null,
            "dateRequestCompulsoryClearing": null,
            "datePostClearanceInspectionReview": null,
            "dateHazardCleared": null,
            "dateTemporaryExemptionGranted": null,
            "dateClosed": null,
            "dateNoticeWithdrawn": null,
            "dateFpnSent": null,
            "infringementSentDate": null,
            "_order": 2
        }
    },
    "count": 2,
    "total": 2,
    "updated": null
}

POST|PUT

Creating (POST) and updating (PUT) items uses a similar structure to the GET response, but only sends one item.

To create an item

POST https://{{host}}/api/json/item
Authorization: Bearer {{token}}
X-Site: {{site}}

To update an item:

PUT https://{{host}}/api/json/item/id/{{id}}
Authorization: Bearer {{token}}
X-Site: {{site}}

For example:

PUT https://{{host}}/api/json/item/id/14968
Authorization: Bearer {{token}}
X-Site: {{site}}

{
  "id": "14968",
  "eventId": "1014",
  "status": "20",
  "type": "fpn",
  "title": "PARCEL 45530943",
  "assetId": "24733",
  "cutGrassWeeds10cm": true,
  "removeDebris": false,
  "firebreak10m": false,
  "cutGrassWeeds5cm": false,
  "trimTrees": false,
  "removeFlammable": false,
  "notes": "This is a note"
}

Matching assets

When linking an asset to an item, you have three approaches:

  • set assetId to the Crisisworks internal ID for the asset,

  • set asset_friendly to a name, and have Crisisworks look up the asset using a its search algorithm, or

  • set asset_lookup to look up a foreign key for the asset, that will match one of the stored foreign keys in the asset's extra property. For example, you can look up by propnum or crefno, if those foreign keys are in your asset dataset. To determine which code to look up, you can specify asset_codefield.

Example: creating an item with an asset looked up based on a property containing propnum.

POST https://{{host}}/api/json/item
Authorization: Bearer {{token}}
X-Site: {{site}}

{
  "eventId": "1014",
  "status": "20",
  "type": "fpn",
  "itemSchemaName": "vicCouncil",
  "asset_lookup": "123456",
  "asset_codefield": "propnum"
}

Example: creating an item with an asset looked up based on a property by a name search.

POST https://{{host}}/api/json/item
Authorization: Bearer {{token}}
X-Site: {{site}}

{
  "eventId": "1014",
  "status": "20",
  "type": "fpn",
  "itemSchemaName": "vicCouncil",
  "asset_friendly": "12 smith street collingwood"
}

Audit Log

This fetches a collection of audit logs, either for a given object (with itemId specified), a given event (with eventId specified) or across the system.

GET https://{{host}}/api/json/log
Authorization: Bearer {{token}}
X-Site: {{site}}

GET Parameters

Keys
Type
Details

limit

Number

When paginating, how many records to return

offset

Number

When paginating, which record to start from

id

String

Load a specific audit log ID

eventId

String

Load all audit logs for an event. Warning, this is a large payload and will need pagination.

itemId

String

Load all audit logs for a given register item

Example

Fetch the audit log for item 14968

GET https://{{host}}/api/json/log?limit=5&item=14968
Authorization: Bearer {{token}}
X-Site: {{site}}

Result

{
    "models": {
        "1004527": {
            "time": "2016-06-20 4:06:27 +0000",
            "id": "1004527",
            "type": "Items",
            "summary": "created a fire prevention notice and set it to hazard exists",
            "message": "",
            "images": [],
            "labels": [
                {
                    "style": "yellow",
                    "label": "Hazard Exists"
                }
            ],
            "dataChangeCount": 10,
            "itemCount": 1,
            "userName": "Pete Kakris",
            "userPosition": "Crisisworks Administrator, FPN Coordinator",
            "userOrganisation": "Datalink",
            "userId": "pkakris.mb",
            "userPositionId": "7",
            "userAvatarUrl": "https:\/\/demo4.crisisworks.com\/var\/files\/thumbs\/80ea44413272ba499ddd0413fc2858cf_57c193f71dbbed2361bce727c9ce1642_w60_h60_fit.png",
            "objId": "14968",
            "objType": "Fire Prevention Notice",
            "objIcon": "ico_hazard_fire.png",
            "title": "PARCEL 45530943",
            "url": "https:\/\/demo4.crisisworks.com\/register\/item\/view\/id\/14968",
            "registerId": "fpn",
            "registerName": "Fire Prevention Notice",
            "eventId": "1014",
            "eventName": "FPN Inspections",
            "assignments": [
                {
                    "id": "pkakris.mb",
                    "name": "Pete Kakris",
                    "type": "Mecc_User",
                    "avatarUrl": "https:\/\/demo4.crisisworks.com\/var\/files\/thumbs\/80ea44413272ba499ddd0413fc2858cf_57c193f71dbbed2361bce727c9ce1642_w60_h60_fit.png"
                }
            ],
            "status": "Hazard Exists",
            "statusClass": "yellow",
            "statusValue": 20,
            "visibility": "",
            "targetUsers": [
                "pkakris.mb"
            ],
            "targetPositions": [],
            "comment": null,
            "targetOrganisations": [],
            "sound": "message_received",
            "logEntries": [
                {
                    "objId": "1031017",
                    "objClass": "Fpn_Inspection",
                    "objTitle": "PARCEL 45530943",
                    "subject": "created a Fire Prevention Notice",
                    "dataChanges": [
                        {
                            "name": "eventId",
                            "label": "Event",
                            "oldValue": "FPN Inspections",
                            "newValue": "FPN Inspections"
                        },
                        {
                            "name": "status",
                            "label": "Status",
                            "oldValue": "",
                            "newValue": "Hazard Exists"
                        },
                        {
                            "name": "assetId",
                            "label": "Asset",
                            "oldValue": "",
                            "newValue": "PARCEL 45530943"
                        },
                        {
                            "name": "cutGrassWeeds10cm",
                            "label": "Cut grass and weeds over the whole property to a height of no more than 10cm.",
                            "oldValue": "",
                            "newValue": "Yes"
                        },
                        {
                            "name": "removeDebris",
                            "label": "Leaves, twigs and other vegetation debris must be removed at regular intervals.",
                            "oldValue": "",
                            "newValue": "No"
                        },
                        {
                            "name": "firebreak10m",
                            "label": "A firebreak of 10 metres wide is to be cut inside the property boundary as close as practicable to the fence-line, to a height of not more than 10cm",
                            "oldValue": "",
                            "newValue": "No"
                        },
                        {
                            "name": "cutGrassWeeds5cm",
                            "label": "Cut all grass and weeds within 30m of any building to a height of no more than 5cm.",
                            "oldValue": "",
                            "newValue": "No"
                        },
                        {
                            "name": "trimTrees",
                            "label": "Trim trees and shrubs clear of roofline, walls and other elements of the buildings.",
                            "oldValue": "",
                            "newValue": "No"
                        },
                        {
                            "name": "removeFlammable",
                            "label": "Remove flammable objects such as firewood, mulches, rubbish and garden furniture from within 10m of the vulnerable parts of the building like windows, decks and eaves.",
                            "oldValue": "",
                            "newValue": "No"
                        },
                        {
                            "name": "assignee",
                            "label": "Assign To",
                            "oldValue": "",
                            "newValue": "Pete K"
                        }
                    ]
                },
                {
                    "objId": "1031018",
                    "objClass": "Fpn_Inspection",
                    "objTitle": "PARCEL 45530943",
                    "subject": "linked to User Pete K"
                }
            ],
            "userOrganisationId": "",
            "subject": "",
            "_order": 1
        }
    },
    "count": 1,
    "total": 1,
    "updated": null
}

Media

Media (photos, videos) are uploaded to Crisisworks and then attached to items.

Creating media

To upload a file, use the /api/binary/file endpoint and POST a multipart/form-data payload with name (the friendly filename) and file (the raw binary payload).

This is equivalent to the way a web browser handles file uploads. This is tricky to do by hand, so you'd typically do this using a library.

The following is a raw HTTP example:

POST https://api.cw.dev.crisisworks.com/api/binary/file
Accept: application/json
Authorization: Bearer {{token}}
X-Site: {{site}}
Content-Type: multipart/form-data; boundary=----CrisisworksBinaryDataFormBoundary
Content-Length: {{content-length}}

------CrisisworksBinaryDataFormBoundary
Content-Disposition: form-data; name="file"; filename="Raising ducks.pdf"
Content-Type: application/pdf

%PDF-1.7...{{raw binary bytes of the PDF, not base64}}...EOF
------CrisisworksBinaryDataFormBoundary
Content-Disposition: form-data; name="filename"

Raising ducks.pdf
------CrisisworksBinaryDataFormBoundary--

Fortunately common HTTP libraries handle this for us.

Here's the above example in BASH:

#!/bin/bash
FILE="Raising ducks.pdf"
TOKEN="your-access-token"
SITE="yoursiteid"
URI="https://yourhost/api/json/file"

curl -X POST "${URI}" \
  -H "Accept: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Site: $SITE" \
  -F "file=@${FILE};type=application/pdf;filename=${FILE}" \
  -F "filename=${FILE}"

And here is the same example in Windows PowerShell:

$FilePath   = "Raising ducks.pdf"
$Token      = "your-access-token"
$Site       = "yoursiteid"
$Uri        = "https://yourhost/api/json/file"

# Build the multipart form
$Form = @{
    file     = Get-Item $FilePath
    filename = [IO.Path]::GetFileName($FilePath)
    comment  = "null"
}

# Send request with headers
Invoke-RestMethod -Uri $Uri -Method Post `
  -Headers @{
      "Accept" = "application/json"
      "Authorization" = "Bearer $Token"
      "X-Site" = $Site
  } `
  -Form $Form

The result contains a unique file ID:

{
    code: 200, 
    message: "OK", 
    id: "1110"
}

You can use this id in future item POST and PUT commands to attach the item:

POST https://{{host}}/api/json/item
Authorization: Bearer {{token}}
X-Site: {{site}}

{
  "__operationTimestamp": "2025-09-17T04:45:45.925Z",
  "type": "wiki",
  "title": "How to raise ducks",
  "body": "<p>A how-to guide on how to raise ducks</p>",
  "itemSchemaName": "document",
  "status": "2",
  "eventId": "20",
  "attachments": [
    {
      "id": "1110",
      "name": "Raising ducks.pdf",
      "type": "application/pdf"
    }
  ]
}

Downloading media

To download a file, use its file ID.

GET https://{{host}}/api/binary/media/id/{{id}}
Authorization: Bearer {{token}}
X-Site: {{site}}

The output will be streamed in binary.

Use your libraries to make this easier. For example, in curl -o allows the destination filename to be specified:

curl -L \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Site: $SITE" \
  -o "my-custom-name.pdf" \
  "https://$HOST/api/binary/media/id/$ID"

Last updated

Was this helpful?