Simple In/Out API v4 Documentation
Welcome to the Simple In/Out API! You can use our API to access Simple In/Out data. You can request both read and write access.
The Simple In/Out v4 API is a RESTful (mostly) API protected by OAuth 2.
Rate Limiting
APIv4 is protected by daily rate limits. Currently, your application can access APIv4 up to 10,000 times per 24 hour period. Every request to APIv4 will return with two headers: X-RateLimit-Limit
and X-RateLimit-Remaining
. X-RateLimit-Limit
will indicate the total number of requests that can be made against APIv4 over a 24 hour period (always 10,000 for now). X-RateLimit-Remaining
will indicate how many requests you have left.
When you’ve run out of requests, APIv4 will return a HTTP status of 429 indicating Too Many Requests.
Expansions
Some of our APIs allow you to include additional information. This saves on API calls, as you can retrieve related information in the primary call and avoid additional requests.
When an API supports including additional information, it does so via the expand
query parameter. This is a comma-delimited list of resources to include. We support expansions via embedding directly into the payload.
The Meta object
Most API payloads include a meta
object to provide additional details about the requested resource(s). This includes paging most often, and sometimes additional information about the user making the request. For some payloads there may be additional items in the meta.
Here’s an example of a meta
object
{"meta": { "paging": { "page": 1, "page_size": 25, "page_count": 2, "count": 47, "previous_page": null, "next_page": 2, "first_href": "https://www.simpleinout.com/api/v4/beacons", "last_href": "https://www.simpleinout.com/api/v4/beacons?page=2", "previous_href": null, "next_href": "https://www.simpleinout.com/api/v4/beacons?page=2" }, "last_updated_at": { "beacons": 1435250484, "favorites": 1437151284, "fences": 1436546484, "groups": 1436287284, "networks": 1436287284, "settings": 1439916084 } }}
Pagination
Pagination occurs when requesting multiple objects. Information about this appears in the meta
object.
Name | Description |
---|---|
page | the page number currently being returned |
page_size | the number of results per page |
page_count | the total number of pages available |
count | the total number of results |
previous_page | the number of the previous page |
next_page | the number of the next page |
first_href | the URL of the API call for the first page of results |
last_href | the URL of the API call for the last page of results |
previous_href | the URL of the API call for the page of results prior to the current page |
next_href | the URL of the API call for the page of results after the current page |
Last Update At
The last_updated_at
attribute in the meta
object returns the epoch time indicating the last time certain resources have been updated. This applies to the authorized user’s company. By storing these dates, you can discover when resources have been updated without having to poll those resources on a regular basis.
If Modified Since and If None Match
Most of the GET requests to the API support the If-Modified-Since and If-None-Match headers. If these two headers are present, the GET request will only return a payload if the relevant data has been updated since the time specified in the If-Modified-Since header and the ETag in the If-None-Match header. If it has been updated since, the payload will be the same as usual. If the data has not been updated, the return will be empty with a HTTP status of 304 (Not Modified). The format of the time is in the HTTP specification, while the ETag should be the same as that returned when a request has been made previously.
When a GET API returns data, the Last-Modified header will be present providing the exact time it’s been modified. This date should be used for future If-Modified-Since requests. The ETag header will be present providing the hash value representing the returned payload. This hash should be used for future If-None-Match requests.
Range Searching
Some integer or date/time fields can be searched by using operators. This permits exact searches, as well as less than, greater than, or between. For these fields, you have an array of options.
- For exact matches, simply include the value. Date/time fields use epoch time, so it’s almost impossible to get an exact match to the second. Examples are
18
or1524168783
. - For ranges based on a single value, you may prepend a symbol to the front of the value. The symbols
<
,>
,<=
, or>=
are supported. Examples are<18
or>=1524168783
. - For between range searches, the
..
operator is used in between the two values. This includes the values on both ends, as well as those in between. Examples are9..18
or1523854800..1524459599
.
Sorting
When requesting multiple objects, most of the time you’ll have some sorting options available. Sorting occurs by passing in the sort
query parameter. The value is a comma-delimited string of fields in the order you wish them to be sorted. By default, all fields will sort in ascending fashion, but you can sort in descending fashion by including a -
sign before the field. An example of this would be sort=name,-begin_at
.
Errors
Error objects in Simple In/Out consist of three parts: code
, message
, and details
.
code
corresponds with those listed below. These provide context as to what type of error occurred.message
is an English plain-text reading of what happened. This should be used for further developer debugging, but should not be relied on to remain consistent over time. While these messages can be displayed to end-users, it is highly discouraged as they can change without notice and they are always going to be in English.details
provides an array of information in the case of validation failures. This will typically be populated with5005
validation errors, though they also can appear with improperly formatted status updates (2002
). The format of the objects in the array arekey: value
pairs, wherebykey
is the name of a field andvalue
is one of a number of possible strings to indicated more specifically what was invalid with the input. Please note that while the key will typically be a parameter on the object, it can occasionally bebase
for errors that fail validation but don’t apply to a particular field.
An example of an error payload:
{ "code": 5005, "message": "Validation Failure: Name can't be blank, UUID is invalid, Beacons exceed company limit of 100", "details": [ { "name": "blank" }, { "uuid": "invalid" }, { "base": "greater_than" } ] }
Error Codes
1002: Company is Disabled
Either the user’s company was on a trial and the trial has expired or the company has let their subscription to Simple In/Out expire. This error will present itself on almost all APIs and will return with the status code 403
.
2002: Status Failure
The status update could not be completed.
5001: Bad Range
The integer or date value/range is invalid.
5002: Unknown Sort
The sort requested does not exist. The full message of this error will provide more explanation.
5003: Unknown Expansion
The expansion requested does not exist. The full message of this error will provide more explanation.
5005: Validation Failure
When attempting to create/update/delete the object, some data was either missing or invalid. The full message of this error will provide more explanation.
5007: Parameters Missing
A required parameter for this API was missing.
5008: Array Required
A parameter which is required to be an array was passed something other than an array.
5009: Unknown Only
The only field requested does not exist. The full message of this error will provide more explanation.
5010: Invalid Float
The floating point number is invalid.
5012: Invalid JSON
The posted JSON body is invalid.
5013: Invalid Page Size of Zero
The page_size parameter cannot be zero.
5014: Invalid mime-type requested
An invalid mime-type was requested.
Error Details
taken
The attribute is not unique
inclusion
The attribute is not in the list of acceptable values
invalid
The attribute is not valid
empty
The attribute cannot be empty
blank
The attribute cannot be blank
too_long
The attribute is too long
not_a_hex
The attribute is not a valid hex color code
not_a_number
The attribute is not a number
not_an_integer
The attribute is not an integer
greater_than
The attribute is greater than a predefined limit
greater_than_or_equal_to
The attribute is greater than or equal to a predefined limit
less_than
The attribute is less than a predefined floor
less_than_or_equal_to
The attribute is greater than or equal to a predefined floor
too_long
The attribute is longer than allowed
too_short
The attribute is shorter than allowed
Forbidden Requests (403)
When the user is authenticated, but doesn’t have the necessary permissions to perform an action,
the server will respond with the status code of 403
and include the user’s privileges in the payload.
Example payload:
{ "company": { "id": "1", "scheduled_statuses": true }, "user": { "id": "5", "roles": { "name": "Regular User", "billing": false "followed_users": false, "reminders": false, "safeties": false, "user_board": true, "manage_company_and_users": false, "manage_groups_and_memberships": false, "manage_others_archives": false, "manage_others_futures": false, "manage_others_status": false, "manage_own_archives": false, "manage_own_futures": true, "manage_own_status": true, "view_others_archives": true, "view_others_futures": true, "view_others_reports": false, "view_user_board_updated_at": true, "member_board": false, "manage_member_archives": false, "manage_member_futures": false, "manage_member_status": false, "view_member_archives": false, "view_member_futures": false, "view_member_reports": false, "created_at": 1506268448, "updated_at": 1506269853 } } }
The privileges payload may not exist on all forbidden responses. In the cases when an error code is used, such as when a company is disabled, only the code and message will be returned.
Web Hooks
Web Hooks are a great way to be notified when something happens inside Simple In/Out. When you add a Web Hook URL to Simple In/Out, we’ll send a request to that URL with JSON in the body to tell you about things that have happened.
Currently, this applies to only three event types: status.new
, status.schedule
, and status.destroy
, though many may be added in the future. It is strongly advised that you code against the type
attribute on the root of the JSON object to avoid new event types being added in the future having unexpected impacts on your code.
The root JSON keys define the basics and out of the box are compatible with Slack’s incoming webhooks. This also means that the text
with be formatted in Markdown. Within the data
object is much of the information specific to Simple In/Out, including ids that can be used in combination with APIv4 to request further information.
{ "username": "Bojack Horseman", "email": "[email protected]", "icon_url": "http://bojackhorseman.com/avatar.gif", "text": "*In*: In Hollywoo", "type": "status.new", "data": { "user_id": "34858", "status": "in", "comment": "In Hollywoo", "created_at": 1448046759, "admin": { "id": "2844", "name": "Princess Carolyn" }, "application": { "id": "84774", "name": "Simple In/Out iOS" } } }