Platio API Programming Guide

Platio API is a Web API that allows you to manipulate records and attachments in a MiniApp you’ve created with Platio Studio. Usually, when you create a MiniApp and deliver it, you’ll browse, create and update records using Platio App, and browse, import and export records using Data Viewer. Platio API is another way to manage records programmatically.

This document describes how you can manage records using Platio API. This document assumes you’re familiar with Platio Studio, Platio App and Data Viewer. If you’re not, please try creating your MiniApp with Platio Studio and using it first.

Note that though Platio API allows you to manage records and attachments in your MiniApp, it doesn’t support creating, updating nor deleting a MiniApp itself. You still need to create and deliver your MiniApp with Platio Studio. Once you’ve delivered your MiniApp, you can access records in the MiniApp using Platio API.

Overview

Terminologies

Before using Platio API, there are some terminologies you need to know. We use some internal names in Platio API, and some names are different from what you see on Platio Studio.

First, a MiniApp is called an Application when you use Platio API. An Application is identified by is its ID. An Application ID is 27-digit string starting with p. pkyfjjjmlyffnlgeb5oh2eqs2aa is an example of an Application ID. You can find an ID of your Application at the Developer page in Data Viewer.

An Application has one or more Collections. Each Data Pocket is associated with a Collection. When you create a new record in a Data Pocket, it’ll be saved in a Collection associated with the Data Pocket. A Collection is like a table in RDB. A Collection also has its ID, which is 8-digit string starting with t like tf71dbb9.

A Collection has a list of Columns which defines what type of values you can put into a Record in the Collection. When you create a field in Platio Studio, it also creates a Column and associated it with the field. Each Column has its ID and its type as well as some other properties. Column ID is a 8-digit string starting with c like c002c2c0. There are some types such as String, Number, Attachment and so on. You can think a Column as a column in RDB.

You can find a list of Collections and Columns at the Developer Page in Data Viewer.

When you create records with Platio App or import records with Data Viewer, they’re stored in a Collection as a Record. Each Record has an ID that is 27-digit string starting with r. ri5f3cykexfbkzk7ohzqm2oocni is an example of a Record ID. You’ll use a Record ID when you get, update, delete a Record.

A Record consists of some Values and metadata. Values are a map from a Column ID to a Value. When you get a Record using Platio API, it’ll look like this.

{
  "id": "ri5f3cykexfbkzk7ohzqm2oocni",
  "createdAt": "2016-07-20T11:39:50.007Z",
  "createdBy": {
    id: "uf598c3f",
    name: "user1"
  },
  "updatedAt": "2016-07-20T11:39:50.007Z",
  "updatedBy": {
    id: "uf598c3f",
    name: "user1"
  },
  "hash": "3a73153a4a7abc176a3fa5dd538b8bda41e9d68d",
  "timestamp": "2016-07-20T11:39:50.050Z",
  "values": {
    "c002c2c0": {
      "type": "String",
      "value": "My Name"
    },
    "cfe0266a": {
      "type": "Attachment",
      "id": "ac2lzz2afdvguze5znhselxd4oe",
      "contentType": "image/jpeg",
      "name": "image.jpeg",
      "size": 254179
    },
    "c915a0bc": {
      "type": "Number",
      "value": 28
    }
  }
}

As you see, each Value has type and other properties. It depends on its type what kind of properties it has. Note that this type must be the same type as a Column type. If a Column type is String, a value for this Column must be of String type, for example. More information about Value and its type are found in Types and Values.

Images, videos, audio are treated as Attachments. When you create a Record with an image, for example, the image itself isn’t stored in the Record, but stored as an Attachment separately. The Record has a Value that refers this Attachment. An Attachment is identified by its ID that is 27-digit string starting with a like ac2lzz2afdvguze5znhselxd4oe.

Each Application has a list of Users. Each User is a pair of a User ID and its name. A User ID is 8-digit string starting with u like uf598c3f. Even though you use its name to login to Platio App and Data Viewer, you need to use its ID to authenticate when you use Platio API.

Prerequisite

As described above, you need to create and deliver a MiniApp before using Platio API. Once you’ve delivered your MiniApp, add a User to it and make them able to use Platio API. To configure a user to be able to use Platio API, check “Allow accessing records and attachments via API” when you add or edit a user.

Endpoints under /v1/management/ are management APIs. To use these more management-oriented actions, you’ll also need to check “Allow managing users via API” in the same page as “Allow accessing records and attachments via API”. For details on management APIs, see the Platio Management API Programming Guide.

Now, login to the MiniApp via Data Viewer and go to the Developer Page. You can find information you need to use Platio API in the page.

In this document, we assume you’ve created a MiniApp with one Data Pocket from Manage Records template with Name text field, Photo image field and Age number field. Here are example information you need. Please replace them with the information you find in the Developer page when you use Platio API.

Endpoint

The endpoint of Platio API is https://api.plat.io/v1/ followed by your Application ID. For example, a URL to get records in the Collection will be https://api.plat.io/v1/pkyfjjjmlyffnlgeb5oh2eqs2aa/collections/tf71dbb9/records.

Format

Platio API mainly uses JSON as a format for requests and responses except for some APIs related to Attachments. For example, getting a Record returns a JSON representation of the Record, and you need to post JSON data to create and update a Record.

This means that Content-Type of a response is application/json, and you need to set Content-Type to application/json when you send a POST or PUT request.

Authentication

When you use Platio API, you must authenticate yourself. Currently, it supports Bearer and Basic authentications, but we recommend you to use Bearer authentication.

Bearer Authentication

To authenticate using Bearer authentication, use your API Token.

This token is generated in the Developer page in Data Viewer. It’s composed by concatenating a token ID and a secret token separated by .. For security reason, a secret token is displayed only at the generation, while a token ID will always be displayed in the Developer page. You will have to revoke a current token and generate a new token if you forget it.

Specify your API Token with Bearer scheme in Authorization header.

Authorization: Bearer t2fde9481edc1a2be612c563d52619b3825f77ff757f16dfcff1d414874731594.S7HAvwFqCUexNe7~PVVEiz-MZkwI2icqLn1RJaS84MANVmiCYq8geIlKsq-K/yrtHTxyXTnF-WXmkZmwWeVt8AK7pyU7E06uv+cSWInqBh7q/yGrtNllwQqss33F5gXLpsyEm4KLcBZ8D2O4-7qXPfAM3YRgBey3ivD5tZTq1-lY8ENIRki~4v6q3bLKHar/aR+0wL8QX+UlFqdOyzNIJ0nhyO5w_7_5Fb_xb4h9VeLc479EPO3X9B_JX09LNcTR

For example, a cURL command to get Records in the Collection using Bearer authentication will be like this.

curl -H 'Authorization: Bearer t2fde9481edc1a2be612c563d52619b3825f77ff757f16dfcff1d414874731594.S7HAvwFqCUexNe7~PVVEiz-MZkwI2icqLn1RJaS84MANVmiCYq8geIlKsq-K/yrtHTxyXTnF-WXmkZmwWeVt8AK7pyU7E06uv+cSWInqBh7q/yGrtNllwQqss33F5gXLpsyEm4KLcBZ8D2O4-7qXPfAM3YRgBey3ivD5tZTq1-lY8ENIRki~4v6q3bLKHar/aR+0wL8QX+UlFqdOyzNIJ0nhyO5w_7_5Fb_xb4h9VeLc479EPO3X9B_JX09LNcTR' \
     'https://api.plat.io/v1/pkyfjjjmlyffnlgeb5oh2eqs2aa/collections/tf71dbb9/records'

Basic Authentication

To authenticate using Basic authentication, use your User ID and password. You cannot use your User name to authenticate.

For example, a cURL command to get Records in the Collection using Basic authentication will be like this.

curl -u uf598c3f:mypassword \
     'https://api.plat.io/v1/pkyfjjjmlyffnlgeb5oh2eqs2aa/collections/tf71dbb9/records'

You cannot use Basic Authentication when Single Sign On is enabled.

Limitations

Request size

The maximum size of each request is 100KB, except for APIs to insert and update records, for which it’s 1MB. For an API to create an attachment, it’s the maximum size of an attachment. The default maximum size of an attachment you can create is 50MB.

You’ll have INVALID_BODY error response when a request is too large.

Number of requests

There are some limits on how many API requests you can make in a certain period. The current limitations are listed below, but they may change. These limitations are applied to each Application.

APIs Limit for Premium Plan Limit for Enterprise Plan
Get Records, a Record, Users, an Application definition 4,000 requests / hour 8,000 requests / hour
Create, Update, Delete a Record, Send a push notification 2,000 requests / hour 4,000 requests / hour
Get an Attachment 500 requests / hour 1,000 requests / hour
Create an Attachment 100 requests / hour 200 requests / hour

Note that the limit applies to all requests in a group. For instance, when you get a list of Records 3,900 times in an hour, you can only get Users 100 times in this period. The counter will be reset every hour.

When it reaches the limit, an API returns 429 response with TOO_MANY_REQUESTS.

Using Platio API

This section describes how you can use Platio API with examples. Please see Platio API References for details of each API.

Manipulating Records

Getting Records

To get Records in a Collection, send a GET request. This API returns the first 100 Records in a specified Collection at most. Records are sorted by their last updated date in descending order.

curl -u uf598c3f:mypassword \
     'https://api.plat.io/v1/pkyfjjjmlyffnlgeb5oh2eqs2aa/collections/tf71dbb9/records'

To get next 100 Records, use skip parameter.

curl -u uf598c3f:mypassword \
     'https://api.plat.io/v1/pkyfjjjmlyffnlgeb5oh2eqs2aa/collections/tf71dbb9/records?skip=100'

To get all Records, call this API multiple times by increasing skip parameter until it returns no Records.

You can also use limit parameter to specify how many Records it returns.

curl -u uf598c3f:mypassword \
     'https://api.plat.io/v1/pkyfjjjmlyffnlgeb5oh2eqs2aa/collections/tf71dbb9/records?skip=100&limit=30'

You can search and sort Records. For example, this line requests Records that matches a search criteria, sorted by Name column in ascending order.

curl -u uf598c3f:mypassword \
     'https://api.plat.io/v1/pkyfjjjmlyffnlgeb5oh2eqs2aa/collections/tf71dbb9/records?search=Name:foo&sortKey=column&sortColumnId=c002c2c0&sortOrder=ascending'

Records can be sorted by their created time, last updated time, creator, updater and a value for a specific column. When you sort records by one of the columns, make sure you made the column sortable.

It depends on a type of a Column how records are sorted by the Column. You can find more about it in Types and Values.

For more about these parameters, take a look at Platio API References. Also, you can find more information about search criteria at Record Query Syntax.

This API returns an array of Records.

[
  {
    "id": "ri5f3cykexfbkzk7ohzqm2oocni",
    "createdAt": "2016-07-20T11:39:50.007Z",
    "createdBy": {
      id: "uf598c3f",
      name: "user1"
    },
    "updatedAt": "2016-07-20T11:39:50.007Z",
    "updatedBy": {
      id: "uf598c3f",
      name: "user1"
    },
    "hash": "3a73153a4a7abc176a3fa5dd538b8bda41e9d68d",
    "timestamp": "2016-07-20T11:39:50.050Z",
    "values": {
      "c002c2c0": {
        "type": "String",
        "value": "My Name"
      },
      "cfe0266a": {
        "type": "Attachment",
        "id": "ac2lzz2afdvguze5znhselxd4oe",
        "contentType": "image/jpeg",
        "name": "image.jpeg",
        "size": 254179
      },
      "c915a0bc": {
        "type": "Number",
        "value": 28
      }
    }
  },
  {
    "id": "rw5zevfgfnne4zoj4sxbbkew4la",
    "createdAt": "2016-07-28T15:12:10.043Z",
    "createdBy": {
      id: "uf598c3f",
      name: "user1"
    },
    "updatedAt": "2016-07-28T15:12:10.043Z",
    "updatedBy": {
      id: "uf598c3f",
      name: "user1"
    },
    "hash": "8f935ee46a603cbbf36c65f1c34653cfb27f199a",
    "timestamp": "2016-07-28T15:12:10.514Z",
    "values": {
      "c002c2c0": {
        "type": "String",
        "value": "Scott Tiger"
      }
    }
  }
]

It returns an empty array when there are no matched records.

Getting a Record

To get a specific Record, send a GET request to the Record.

curl -u uf598c3f:mypassword \
     'https://api.plat.io/v1/pkyfjjjmlyffnlgeb5oh2eqs2aa/collections/tf71dbb9/records/ri5f3cykexfbkzk7ohzqm2oocni'

This API returns a specified record.

{
  "id": "ri5f3cykexfbkzk7ohzqm2oocni",
  "createdAt": "2016-07-20T11:39:50.007Z",
  "createdBy": {
    id: "uf598c3f",
    name: "user1"
  },
  "updatedAt": "2016-07-20T11:39:50.007Z",
  "updatedBy": {
    id: "uf598c3f",
    name: "user1"
  },
  "hash": "3a73153a4a7abc176a3fa5dd538b8bda41e9d68d",
  "timestamp": "2016-07-20T11:39:50.050Z",
  "values": {
    "c002c2c0": {
      "type": "String",
      "value": "My Name"
    },
    "cfe0266a": {
      "type": "Attachment",
      "id": "ac2lzz2afdvguze5znhselxd4oe",
      "contentType": "image/jpeg",
      "name": "image.jpeg",
      "size": 254179
    },
    "c915a0bc": {
      "type": "Number",
      "value": 28
    }
  }
}

Creating a Record

To create a new Record, send a POST request.

curl -u uf598c3f:mypassword \
     -X POST \
     -H 'Content-Type: application/json' \
     -d '{"values":{"c002c2c0":{"type":"String","value":"Scott Tiger"}}}' \
     'https://api.plat.io/v1/pkyfjjjmlyffnlgeb5oh2eqs2aa/collections/tf71dbb9/records'

A request body needs to contain values property which is a mapping from Column IDs to Values. Please take a look at Types and Values for details.

This API returns the created Record.

{
  "id": "rw5zevfgfnne4zoj4sxbbkew4la",
  "createdAt": "2016-07-28T15:12:10.043Z",
  "createdBy": {
    id: "uf598c3f",
    name: "user1"
  },
  "updatedAt": "2016-07-28T15:12:10.043Z",
  "updatedBy": {
    id: "uf598c3f",
    name: "user1"
  },
  "hash": "8f935ee46a603cbbf36c65f1c34653cfb27f199a",
  "timestamp": "2016-07-28T15:12:10.514Z",
  "values": {
    "c002c2c0": {
      "type": "String",
      "value": "Scott Tiger"
    }
  }
}

If you’re an admin user of this Application, you can specify optional creatorId property as well. When you specify this parameter, a creator of the record will be this user instead of yourself. You can find User IDs of other users with an API to get Users.

curl -u uf598c3f:mypassword \
     -X POST \
     -H 'Content-Type: application/json' \
     -d '{"values":{"c002c2c0":{"type":"String","value":"Scott Tiger"}},"creatorId":"u7ecc403"}' \
     'https://api.plat.io/v1/pkyfjjjmlyffnlgeb5oh2eqs2aa/collections/tf71dbb9/records'

As you see, createdBy and updatedBy of the created record will be the specified user.

{
  "id": "rw5zevfgfnne4zoj4sxbbkew4la",
  "createdAt": "2016-07-28T15:12:10.043Z",
  "createdBy": {
    id: "u7ecc403",
    name: "user2"
  },
  "updatedAt": "2016-07-28T15:12:10.043Z",
  "updatedBy": {
    id: "u7ecc403",
    name: "user2"
  },
  "hash": "8f935ee46a603cbbf36c65f1c34653cfb27f199a",
  "timestamp": "2016-07-28T15:12:10.514Z",
  "values": {
    "c002c2c0": {
      "type": "String",
      "value": "Scott Tiger"
    }
  }
}

Creating Records

To create multiple Records, send a POST request. Use the same URL as creating a Record, but pass an array of objects instead of an object. You can create 100 Records at most per request.

curl -u uf598c3f:mypassword \
     -X POST \
     -H 'Content-Type: application/json' \
     -d '[{"values":{"c002c2c0":{"type":"String","value":"Scott Tiger"}}},{"values":{"c002c2c0":{"type":"String","value":"Mike Deer"}}}]' \
     'https://api.plat.io/v1/pkyfjjjmlyffnlgeb5oh2eqs2aa/collections/tf71dbb9/records'

This API returns the created Records.

[
  {
    "id": "rw5zevfgfnne4zoj4sxbbkew4la",
    "createdAt": "2016-07-28T15:12:10.043Z",
    "createdBy": {
      id: "uf598c3f",
      name: "user1"
    },
    "updatedAt": "2016-07-28T15:12:10.043Z",
    "updatedBy": {
      id: "uf598c3f",
      name: "user1"
    },
    "hash": "8f935ee46a603cbbf36c65f1c34653cfb27f199a",
    "timestamp": "2016-07-28T15:12:10.514Z",
    "values": {
      "c002c2c0": {
        "type": "String",
        "value": "Scott Tiger"
      }
    }
  },
  {
    "id": "rt5yjwvcfznel5jql73pxn7rz5u",
    "createdAt": "2016-08-28T15:12:10.043Z",
    "createdBy": {
      id: "uf598c3f",
      name: "user1"
    },
    "updatedAt": "2016-08-28T15:12:10.043Z",
    "updatedBy": {
      id: "uf598c3f",
      name: "user1"
    },
    "hash": "3d6d2537a343d3a82be6141858165fc0768dc941",
    "timestamp": "2016-08-28T15:12:10.514Z",
    "values": {
      "c002c2c0": {
        "type": "String",
        "value": "Mike Deer"
      }
    }
  }
]

If you’re an admin user of this Application, you can specify optional creatorId property of each record to set their creator. You need to specify creators of all Records when you specify creators.

curl -u uf598c3f:mypassword \
     -X POST \
     -H 'Content-Type: application/json' \
     -d '[{"values":{"c002c2c0":{"type":"String","value":"Scott Tiger"}},"creatorId":"u7ecc403"},{"values":{"c002c2c0":{"type":"String","value":"Mike Deer"}},"creatorId":"uf598c3f"}]' \
     'https://api.plat.io/v1/pkyfjjjmlyffnlgeb5oh2eqs2aa/collections/tf71dbb9/records'

An error can occur after it has created some Records, for instance, when there is a duplicated value for a unique Column. Records preceding that Record will be created in this case. Also, an error response will contain Records that have been created before the error.

{
  "code": "DUPLICATED_VALUES",
  "params": {
    "duplicatedValues": [
      {
        "columnId": "c002c2c0",
        "value": "Mike Deer",
      }
    ],
    "recordIndex": 1,
    "insertedRecords": [
      {
        "id": "rw5zevfgfnne4zoj4sxbbkew4la",
        "createdAt": "2016-07-28T15:12:10.043Z",
        "createdBy": {
          id: "uf598c3f",
          name: "user1"
        },
        "updatedAt": "2016-07-28T15:12:10.043Z",
        "updatedBy": {
          id: "uf598c3f",
          name: "user1"
        },
        "hash": "8f935ee46a603cbbf36c65f1c34653cfb27f199a",
        "timestamp": "2016-07-28T15:12:10.514Z",
        "values": {
          "c002c2c0": {
            "type": "String",
            "value": "Scott Tiger"
          }
        }
      }
    ]
  }
}

Updating a Record

To update an existing Record, send a PUT request.

curl -u uf598c3f:mypassword \
     -X PUT \
     -H 'Content-Type: application/json' \
     -d '{"values":{"c002c2c0":{"type":"String","value":"Jeff Scott"}}}' \
     'https://api.plat.io/v1/pkyfjjjmlyffnlgeb5oh2eqs2aa/collections/tf71dbb9/records/ri5f3cykexfbkzk7ohzqm2oocni'

A request body needs to contain values property which is a mapping from Column IDs to Values. Please take a look at Types and Values for details.

By default, this API replaces all Values of the Record. If you don’t specify a Value for a Column, it’ll remove an existing Value for the Column.

Set replace property to false when you want to replace only values in values property. Use null as a value to delete a value.

curl -u uf598c3f:mypassword \
     -X PUT \
     -H 'Content-Type: application/json' \
     -d '{"values":{"c002c2c0":{"type":"String","value":"Jeff Scott"},"c915a0bc":null},"replace":false}' \
     'https://api.plat.io/v1/pkyfjjjmlyffnlgeb5oh2eqs2aa/collections/tf71dbb9/records/ri5f3cykexfbkzk7ohzqm2oocni'

This API returns the updated Record.

{
  "id": "ri5f3cykexfbkzk7ohzqm2oocni",
  "createdAt": "2016-07-28T15:12:10.043Z",
  "createdBy": {
    id: "uf598c3f",
    name: "user1"
  },
  "updatedAt": "2016-08-14T01:43:10.165Z",
  "updatedBy": {
    id: "uf598c3f",
    name: "user1"
  },
  "hash": "8f935ee46a603cbbf36c65f1c34653cfb27f199a",
  "timestamp": "2016-08-14T01:43:10.254Z",
  "values": {
    "c002c2c0": {
      "type": "String",
      "value": "Jeff Scott"
    }
  }
}

Updating Records

To update multiple existing Records, send a PUT request. You can update 100 Records at most per request.

curl -u uf598c3f:mypassword \
     -X PUT \
     -H 'Content-Type: application/json' \
     'https://api.plat.io/v1/pkyfjjjmlyffnlgeb5oh2eqs2aa/collections/tf71dbb9/records' \
     -d @- <<'EOF'
[
  {
    "id":"ri5f3cykexfbkzk7ohzqm2oocni",
    "values": {
      "c002c2c0": {
        "type": "String",
        "value": "Jeff Scott"
      }
    }
  },
  {
    "id":"rw5zevfgfnne4zoj4sxbbkew4la",
    "values": {
      "c002c2c0": {
        "type": "String",
        "value": "Mike Deer"
      }
    }
  }
]
EOF

A request body needs to be an array of objects that contains id property which indicates the Record to be updated and values property which is a mapping from Column IDs to Values. Please take a look at Types and Values for details.

Just like Updating a Record, this API replaces all Values of the Records. If you don’t specify a Value for a Column, it’ll remove an existing Value for the Column.

Set replace property to false for every object where you want to replace only values in values property. Use null as a value to delete a value.

curl -u uf598c3f:mypassword \
     -X PUT \
     -H 'Content-Type: application/json' \
     'https://api.plat.io/v1/pkyfjjjmlyffnlgeb5oh2eqs2aa/collections/tf71dbb9/records' \
     -d @- <<'EOF'
[
  {
    "id":"ri5f3cykexfbkzk7ohzqm2oocni",
    "values": {
      "c002c2c0": {
        "type": "String",
        "value": "Jeff Scott"
      },
      "c915a0bc":null
    },
    "replace":false
  },
  {
    "id":"rw5zevfgfnne4zoj4sxbbkew4la",
    "values": {
      "c002c2c0": {
        "type": "String",
        "value": "Mike Deer"
      },
      "c915a0bc": null
    },
    "replace": false
  }
]
EOF

This API returns the list of updated Records.

[
    {
      "id": "ri5f3cykexfbkzk7ohzqm2oocni",
      "createdAt": "2016-07-28T15:12:10.043Z",
      "createdBy": {
        id: "uf598c3f",
        name: "user1"
      },
      "updatedAt": "2016-08-14T01:43:10.165Z",
      "updatedBy": {
        id: "uf598c3f",
        name: "user1"
      },
      "hash": "8f935ee46a603cbbf36c65f1c34653cfb27f199a",
      "timestamp": "2016-08-14T01:43:10.254Z",
      "values": {
        "c002c2c0": {
          "type": "String",
          "value": "Jeff Scott"
        }
      }
    },
    {
      "id": "rt5yjwvcfznel5jql73pxn7rz5u",
      "createdAt": "2016-08-28T15:12:10.043Z",
      "createdBy": {
        id: "uf598c3f",
        name: "user1"
      },
      "updatedAt": "2016-08-28T15:12:10.043Z",
      "updatedBy": {
        id: "uf598c3f",
        name: "user1"
      },
      "hash": "3d6d2537a343d3a82be6141858165fc0768dc941",
      "timestamp": "2016-08-28T15:12:10.514Z",
      "values": {
        "c002c2c0": {
          "type": "String",
          "value": "Mike Deer"
        }
      }
    }
]

An error can occur after it has updated some Records, for instance, when there is a duplicated value for a unique Column. Records preceding that Record will be updated in this case. Also, an error response will contain Records that have been updated before the error.

{
  "code": "DUPLICATED_VALUES",
  "params": {
    "duplicatedValues": [
      {
        "columnId": "c002c2c0",
        "value": "Mike Deer",
      }
    ],
    "recordIndex": 1,
    "updatedRecords": [
      {
        "id": "rw5zevfgfnne4zoj4sxbbkew4la",
        "createdAt": "2016-07-28T15:12:10.043Z",
        "createdBy": {
          id: "uf598c3f",
          name: "user1"
        },
        "updatedAt": "2016-07-28T15:12:10.043Z",
        "updatedBy": {
          id: "uf598c3f",
          name: "user1"
        },
        "hash": "8f935ee46a603cbbf36c65f1c34653cfb27f199a",
        "timestamp": "2016-07-28T15:12:10.514Z",
        "values": {
          "c002c2c0": {
            "type": "String",
            "value": "Scott Tiger"
          }
        }
      }
    ]
  }
}

Upserting a Record

To upsert a Record, send a PATCH request to a URL containing a key Column ID. It searches for a record by the value for the key Column and updates it. It creates a new Record otherwise.

In the following example, it’ll update the Record with the specified values if there is such a Record whose value for the Column with ID c002c2c0 is Scott Tiger. It’ll create a new Record with the specified values otherwise.

curl -u uf598c3f:mypassword \
     -X PATCH \
     -H 'Content-Type: application/json' \
    'https://api.plat.io/v1/pkyfjjjmlyffnlgeb5oh2eqs2aa/collections/tf71dbb9/records/upsert/c002c2c0' \
    -d @- <<'EOF'
{
  "values": {
    "c002c2c0": {
      "type": "String",
      "value": "Scott Tiger"
    },
    "cf598c3f": {
      "type": "Number",
      "value": 5
    }
  }
}
EOF

A request body needs to contain values property which is a mapping from Column IDs to Values. Please take a look at Types and Values for details.

You need to specify a proper value for the key Column in values. MISSING_UPSERT_KEY_VALUE error will occur otherwise.

It replaces only values in values property. In other words, it behaves just like you specify false as replace parameter when Updating a Record.

This API returns the upserted Record.

{
  "id": "rw5zevfgfnne4zoj4sxbbkew4la",
  "createdAt": "2016-07-28T15:12:10.043Z",
  "createdBy": {
    id: "uf598c3f",
    name: "user1"
  },
  "updatedAt": "2016-07-28T15:12:10.043Z",
  "updatedBy": {
    id: "uf598c3f",
    name: "user1"
  },
  "hash": "8f935ee46a603cbbf36c65f1c34653cfb27f199a",
  "timestamp": "2016-07-28T15:12:10.514Z",
  "values": {
    "c002c2c0": {
      "type": "String",
      "value": "Scott Tiger"
    }
  }
}

If you’re an admin user of this Application, you can specify optional creatorId property as well. When you specify this parameter, a creator of the record will be this user instead of yourself when this API creates a new record. You can find User IDs of other users with an API to get Users.

curl -u uf598c3f:mypassword \
     -X PATCH \
     -H 'Content-Type: application/json' \
    'https://api.plat.io/v1/pkyfjjjmlyffnlgeb5oh2eqs2aa/collections/tf71dbb9/records/upsert/c002c2c0' \
    -d @- <<'EOF'
{
  "values": {
    "c002c2c0": {
      "type": "String",
      "value": "Scott Tiger"
    },
    "cf598c3f": {
      "type": "Number",
      "value": 5
    }
  },
  "creatorId": "u7ecc403"
}
EOF

As you see, createdBy and updatedBy of the created record will be the specified user.

{
  "id": "rw5zevfgfnne4zoj4sxbbkew4la",
  "createdAt": "2016-07-28T15:12:10.043Z",
  "createdBy": {
    id: "u7ecc403",
    name: "user2"
  },
  "updatedAt": "2016-07-28T15:12:10.043Z",
  "updatedBy": {
    id: "u7ecc403",
    name: "user2"
  },
  "hash": "8f935ee46a603cbbf36c65f1c34653cfb27f199a",
  "timestamp": "2016-07-28T15:12:10.514Z",
  "values": {
    "c002c2c0": {
      "type": "String",
      "value": "Scott Tiger"
    }
  }
}

Upserting Records

To upsert multiple Records, send a PATCH request. Use the same URL as Upserting a Record, but pass an array of objects instead of an object. You can upsert 100 Records at most per request.

Please refer to Upserting a Record for details of its behavior.

curl -u uf598c3f:mypassword \
     -X PATCH \
     -H 'Content-Type: application/json' \
    'https://api.plat.io/v1/pkyfjjjmlyffnlgeb5oh2eqs2aa/collections/tf71dbb9/records/upsert/c002c2c0' \
    -d @- <<'EOF'
[
  {
    "values": {
      "c002c2c0": {
        "type": "String",
        "value": "Scott Tiger"
      }
    }
  },
  {
    "values": {
      "c002c2c0": {
         "type": "String",
         "value": "Mike Deer"
      }
    }
  }
]
EOF

This API returns the upserted Records.

[
  {
    "id": "rw5zevfgfnne4zoj4sxbbkew4la",
    "createdAt": "2016-07-28T15:12:10.043Z",
    "createdBy": {
      id: "uf598c3f",
      name: "user1"
    },
    "updatedAt": "2016-07-28T15:12:10.043Z",
    "updatedBy": {
      id: "uf598c3f",
      name: "user1"
    },
    "hash": "8f935ee46a603cbbf36c65f1c34653cfb27f199a",
    "timestamp": "2016-07-28T15:12:10.514Z",
    "values": {
      "c002c2c0": {
        "type": "String",
        "value": "Scott Tiger"
      }
    }
  },
  {
    "id": "rt5yjwvcfznel5jql73pxn7rz5u",
    "createdAt": "2016-08-28T15:12:10.043Z",
    "createdBy": {
      id: "uf598c3f",
      name: "user1"
    },
    "updatedAt": "2016-08-28T15:12:10.043Z",
    "updatedBy": {
      id: "uf598c3f",
      name: "user1"
    },
    "hash": "3d6d2537a343d3a82be6141858165fc0768dc941",
    "timestamp": "2016-08-28T15:12:10.514Z",
    "values": {
      "c002c2c0": {
        "type": "String",
        "value": "Mike Deer"
      }
    }
  }
]

If you’re an admin user of this Application, you can specify optional creatorId property of each record to set their creator when this API creates a new record. You need to specify creators of all Records when you specify creators.

curl -u uf598c3f:mypassword \
     -X PATCH \
     -H 'Content-Type: application/json' \
     'https://api.plat.io/v1/pkyfjjjmlyffnlgeb5oh2eqs2aa/collections/tf71dbb9/records/upsert/c002c2c0' \
     -d @- <<'EOF'
[
  {
    "values": {
      "c002c2c0": {
        "type": "String",
        "value": "Scott Tiger"
      }
    },
    "creatorId": "u7ecc403"
  },
  {
    "values": {
      "c002c2c0": {
        "type": "String",
        "value": "Mike Deer"
      }
    },
    "creatorId": "uf598c3f"
  }
]
EOF

An error can occur after it has upserted some Records, for instance, when there is a duplicated value for a unique Column. Records preceding that Record will be upserted in this case. Also, an error response will contain Records that have been upserted before the error.

{
  "code": "DUPLICATED_VALUES",
  "params": {
    "duplicatedValues": [
      {
        "columnId": "c002c2c0",
        "value": "Mike Deer",
      }
    ],
    "recordIndex": 1,
    "upsertedRecords": [
      {
        "id": "rw5zevfgfnne4zoj4sxbbkew4la",
        "createdAt": "2016-07-28T15:12:10.043Z",
        "createdBy": {
          id: "uf598c3f",
          name: "user1"
        },
        "updatedAt": "2016-07-28T15:12:10.043Z",
        "updatedBy": {
          id: "uf598c3f",
          name: "user1"
        },
        "hash": "8f935ee46a603cbbf36c65f1c34653cfb27f199a",
        "timestamp": "2016-07-28T15:12:10.514Z",
        "values": {
          "c002c2c0": {
            "type": "String",
            "value": "Scott Tiger"
          }
        }
      }
    ]
  }
}

Deleting a Record

To delete an existing Record, send a DELETE request.

curl -u uf598c3f:mypassword \
     -X DELETE \
     'https://api.plat.io/v1/pkyfjjjmlyffnlgeb5oh2eqs2aa/collections/tf71dbb9/records/ri5f3cykexfbkzk7ohzqm2oocni'

This API returns nothing with 204 status code.

Deleting Records

To delete multiple existing Records, send a DELETE request.

curl -u uf598c3f:mypassword \
     -X DELETE \
     'https://api.plat.io/v1/pkyfjjjmlyffnlgeb5oh2eqs2aa/collections/tf71dbb9/records'

Use search parameter to specify which Records to be deleted.

curl -u uf598c3f:mypassword \
     -X DELETE \
     'https://api.plat.io/v1/pkyfjjjmlyffnlgeb5oh2eqs2aa/collections/tf71dbb9/records?search=Name:foo'

Use limit parameter to specify the maximum number of records to delete. A request may time out when you try to delete too many records at once. In this case, you can send multiple requests with a proper limit parameter to delete all records.

For more about parameters, take a look at Platio API References. Also, you can find more information about search criteria at Record Query Syntax.

This API returns nothing with 204 status code when you don’t specify limit parameter. It returns the number of deleted records with 200 status code when you specify limit parameter.

{
  "deletedCount": 5345
}

Some records might have been deleted even when this API returns an error.

Manipulating Attachments

Getting an Attachment

You can get an Attachment with a GET request to an Attachment.

curl -u uf598c3f:mypassword \
     'https://api.plat.io/v1/pkyfjjjmlyffnlgeb5oh2eqs2aa/collections/tf71dbb9/attachments/ac2lzz2afdvguze5znhselxd4oe'

The response is an attachment itself, and you can get its Content-Type and file name from Content-Type header and Content-Disposition header respectively.

Note that an Attachment may not available even when a Record referring the Attachment is available. This is because Attachments are uploaded to a server separately from Records asynchronously. When you get 404 response from this API, retry after a certain period. It may take a few seconds to few days before you can get the Attachment when Platio App goes offline before uploading it, for example.

Creating an Attachment

To create a Record with an Attachment value, create an Attachment first. You can upload a file by sending a POST request, and it’ll return an ID of a created Attachment. You can use this ID to create a Record.

When you upload a file to create an Attachment, don’t forget to include Content-Type and Content-Disposition headers.

curl -u uf598c3f:mypassword \
     -X POST \
     -H 'Content-Type: image/jpeg' \
     -H 'Content-Disposition: attachment; filename=image.jpeg' \
     --data-binary @image.jpeg \
     'https://api.plat.io/v1/pkyfjjjmlyffnlgeb5oh2eqs2aa/collections/tf71dbb9/attachments'

This example assumes you have image.jpeg in the current directory.

If you’re an admin user of this Application, you can specify optional X-Platio-CreatorId header as well. When you specify this header, a creator of the attachment will be this user instead of yourself. You can find User IDs of other users with an API to get Users.

curl -u uf598c3f:mypassword \
     -X POST \
     -H 'Content-Type: image/jpeg' \
     -H 'Content-Disposition: attachment; filename=image.jpeg' \
     -H 'X-Platio-CreatorId: u7ecc403' \
     --data-binary @image.jpeg \
     'https://api.plat.io/v1/pkyfjjjmlyffnlgeb5oh2eqs2aa/collections/tf71dbb9/attachments'

Manipulating Users

Getting Users

To get Users of an Application, send a GET request. This API returns the first 100 Users in an Application at most. Users are sorted by their names in ascending order.

curl -u uf598c3f:mypassword \
     'https://api.plat.io/v1/pkyfjjjmlyffnlgeb5oh2eqs2aa/users'

To get next 100 Users, use skip parameter.

curl -u uf598c3f:mypassword \
     'https://api.plat.io/v1/pkyfjjjmlyffnlgeb5oh2eqs2aa/users?skip=100'

To get all Users, call this API multiple times by increasing skip parameter until it returns no Users.

You can also use limit parameter to specify how many Users it returns.

curl -u uf598c3f:mypassword \
     'https://api.plat.io/v1/pkyfjjjmlyffnlgeb5oh2eqs2aa/users?skip=100&limit=30'

Use search parameter to filter Users to be returned. Users whose names contain a value of this parameter in case-sensitive manner will be returned.

curl -u uf598c3f:mypassword \
     'https://api.plat.io/v1/pkyfjjjmlyffnlgeb5oh2eqs2aa/users?search=user'

This API returns an array of Users.

[
  {
    "id": "uf598c3f",
    "name": "user1"
  },
  {
    "id": "u7ecc403",
    "name": "user2"
  }
]

You can use these Users in User values, as well as use their IDs as a creator when you create a Record.

Sending a push notification to a User

You can send a push notification to a User with the API. Make sure to configure your application to enable push notifications. Also you must be an admin of the MiniApp to send push notifications.

curl -u uf598c3f:mypassword \
     -X POST \
     -H 'Content-Type: application/json' \
     -d '{"title":"Warning!","body":"The temperature is too high.","sound":"default"}' \
     'https://api.plat.io/v1/pkyfjjjmlyffnlgeb5oh2eqs2aa/users/uf598c3f/notifications'

Set a title of the notification to title property and a body to body property. You may specify a string shorter than or equal to 128 and 512 characters respectively.

You can also specify a URL shorter than or equal to 1024 characters to url property. The Platio App opens this URL when a user taps the notification. You can use Platio URL to open a specified Data Pocket or a Record.

It plays a sound when you specify default to sound property. Don’t specify this property not to play a sound.

This API returns nothing with 204 status code.

Note that a user may not receive a notification even when this API succeeds. They don’t receive notifications when, for example, they’ve logged out from the MiniApp or configured not to receive notifications at the OS settings.

Manipulating Application

Getting an Application definition

To get a definition of an Application, send a GET request to the Application.

curl -u uf598c3f:mypassword \
     'https://api.plat.io/v1/pkyfjjjmlyffnlgeb5oh2eqs2aa'

This API returns a definition of an Application, with the details of the Collection definitions and Column definitions. You can find the details of a returned object in Platio API References.

{
  "id": "pkyfjjjmlyffnlgeb5oh2eqs2aa",
  "version": 7,
  "name": "Sample",
  "sharedUsersModeEnabled": false,
  "teamsModeEnabled": false,
  "url": "https://app.plat.io/app/Demo/Sample",
  "collections": [
    {
      "id": "tf71dbb9",
      "name": "Sample",
      "readAccessType": "everyone",
      "writeAccessType": "creatorOnly",
      "columns": [
        {
          "id": "c002c2c0",
          "name": "Name",
          "type": "String",
          "unique": false,
          "sortable": true,
          "searchable": true
        },
        {
          "id": "cfe0266a",
          "name": "Photo",
          "type": "Attachment",
          "unique": false,
          "sortable": false,
          "searchable": false
        },
        {
          "id": "c915a0bc",
          "name": "Age",
          "type": "Number",
          "unique": false,
          "sortable": false,
          "searchable": true
        }
      ]
    }
  ]
}

Handling errors

When something went wrong, Platio API returns an error. It reports an error using HTTP status code along with a JSON response containing error code.

For authentication errors, it returns 401 status code. It returns 400 or 404 status code if a request is not valid. It may return 500 or 503 status code when something really went wrong on a server.

Check Platio API Errors for more information about error codes.