Ubiregi API

Ubiregi is simple and clean yet powerful; so the API is.

Introduction

Ubiregi API allows third parties to develop systems which interact with Ubiregi data, including menus, tags, customers, and checkouts.

Using Ubiregi API, you can develop your own application for:

  • Editing menus with your legacy excellent system
  • Importing sales data into your legacy great system
  • Advanced sales analysis
  • Advanced stock control
  • Booking

and, such features essential for your or your clients' business.

Ubiregi API provides almost full access to Ubiregi's data. Everything except authentication is the same with what the Ubiregi app is doing. (In fact, the API v3 is essentially more powerful than API v2, which is used by Ubiregi 2.x)

Quick Start

  1. Sign-up to ubiregi.com
  2. Register for developer account and new application
  3. Install the application on your account
  4. Download the examples.
  5. Change the sample app, and it is your app now!

General Notes Things every developer should know

Github project

We have github project to communicate with Ubiregi API users. It has an issue tracker, and we are using it.

Note All issues, but security related ones, are expected to be reported on the tracker. Think twice before you send me an email to report an issue.

The API is Entirely HTTP-based, and Almost RESTful

Methods to retrieve data from the Ubiregi API requires a GET request. Methods to create new things requires a POST request. And to update things requires a PUT request. Most methods requires a particular HTTP method and will return an error if you do not make your request with the correct one.

The API is almost RESTful. Every operations are update of attributes of resources.

Ubiregi Web App is Built on Rails

We use Ruby on Rails 3 to develop ubiregi.com web app. You may find something odd our api. It should be because of Rails requirements.

We carefully described things non-rails-developer should mention about, but may be insufficient. If you have some problem, you may need to check Rails related documents.

JSON is Used

We use JSON for every structured data. It implies that binary data are encoded with base64 and non-ascii characters are UTF8 encoded.

POST request should be send with HTTP header Content-Type: application/json.

Use HTTPS

All requests to Ubiregi API must be HTTPS requests.

Examples

Ubiregi-API-Client for Scala
Simple library which abstracts API calls and authentications, for Scala.

Authentication with API Token

Ubiregi API provides very simple authentication mechanism using pre-shared token. This way is recommended to start developing your own apps which is integrated with Ubiregi. However, if you are planning to allow many users to use your app, it is recommended to use OAuth2 for authentication.

Prepare API Token

Ubiregi users can generate API access tokens, in Ubiregi web app.

  1. Visit account setting page
  2. Click 新しく作成 button of APIアクセストークン section
  3. Put name of the app; this is optional and used to identify your app
  4. Click 作成 button
  5. Click 表示 button of new added item on the page to see the token string

Your user, who is trying to use your app with a Ubiregi account, have to share the token with your app. The simplest way to do that should be the following.

  1. Prepare a form to put API token in your app
  2. Ask your user to copy & paste from the dialog shown above

Authorizing API Requests

Put the following http request header in all your API requests.

X-Ubiregi-Auth-Token The authentication token of the user for your app installation. This is used for authentication.

There is no expiration. The exception is when your user explicitly canceled the authorization to your app.

Authentication with OAuth2

Ubiregi API access is managed in the OAuth2 manner. You should consult to OAuth2 spec for details.

App Registration

Visit Ubiregi Developer Dashboard to register your app.

Remarks

  • Ubiregi apps are not necessary to have an https redirect URI (http can be used; although it is not recommended.)
  • Ubiregi apps can not have multiple redirect URIs
  • Public client means the app does not have an credential to be authenticated. The publicity can not be changed later.

Getting Authorized

Make your user's UA to access at https://ubiregi.com/oauth2/authorize endpoint. The endpoint accepts several query parameters.

client_id Your client's ID (OAuth2)
state To pass a parameter to your callback. (OAuth2)
force_login Give true if you want your user to input their username and password. (Default: false)
force_authorize Give true if you want your user to click "Authorize" button before your app got authorized. (Default: false; if your user is trying to authorize your app again, it skips to prompt "Authorize" button.)
mobile Give true if your user's UA is mobile device (small screen). (Default: false)

Working with Token

https://ubiregi.com/oauth2/token is the token endpoint. POST HTTP request following OAuth2 protocol to:

  • Obtain an Access Token using Access Grant
  • Refresh Access Token using Refresh Token

Token Response

The token endpoint access response is a JSON object like the following.

{
  "access_token": $token,
  "token_type": "bearer",
  "expires_in": $seconds,
  "refresh_token": $token,
  "refresh_token_expires_in": $seconds,
  "account_id": $account_id
}

Most fields are ones of OAuth2, but refresh_token_expires_in and account_id are extension by Ubiregi API.

access_token
Access token.
token_type
Always bearer.
expires_in
Seconds remain to access token expiration.
refresh_token
Refresh token.
refresh_token_expires_in
Seconds remain to refresh token expiration. This is an extension by Ubiregi API.
account_id
ID of the account which authenticated with the token. This is an extension by Ubiregi API.

Access token and refresh token will expire. Access token expiration is in 24 hours, and refresh token expiration is in 14 days in current implementation. This is just because of implementation. We may change them.

Obtaining Access Token

POST a request with grant_type=authorization_code to obtain an access_token. This is standard OAuth2 request and other parameters specified by OAuth2 will be accepted.

Ubiregi API issues new access token for each authorization_code request. This might be annoying to your client since one account may have many access tokens. account_id field is a remedy to this. Invalidate all access tokens associated with the account_id already issued and stored in your database, and you can keep your DB clean.

Refreshing Access Token

POST a request with grant_type=refresh_token to refresh an access_token. This is standard OAuth2 request and other parameters specified by OAuth2 will be accepted.

It is completely okay if you refresh your token even if it is not expired. It invalidates the old access token, and issues new access token and refresh token pair.

Accessing API with Token

Give an Authorization HTTP request header in the following syntax.

Authorization: Bearer 2948or823934y8w9dfit834

If the token is invalid or expired, the request will result in 401 and WWW-Authenticate header will be Bearer error="invalid_token". You may refresh access token using refresh token previously issued.

Account Expiration

Account may be expired.
Expired account at time t
If an account does not have valid subscription at time t, the account is expired.
Visible checkouts
Checkouts which can be downloaded from ubiregi.com server. The computation of monthly sales and so on only takes visible checkouts as their input.
Invisible checkouts
Checkouts which can not be downloaded from ubiregi.com server. Invisible checkouts will be ignored, but they are stored on ubiregi.com server.
Expired checkout at time t
Checkouts, where its account is expired at its paid_at and closed.
  • Expired checkout at time t is invisible.
  • Checkouts where its paid_at is less than 3 days (72 hours) ago from t is visible, even if they are expired.

The definition of checkout visibility is described in the following figure. Green and gray dots are visible and invisible checkouts respectively (assume all checkouts are closed). Group of visible checkouts in left is because the existence of a subscription. Another group of visible checkouts in right is because its paid_at is new.

These definitions about checkout visibility may cause a problem, when your user's account is expired and your user is using CRM. Customer's history may have a reference to invisible checkouts.


Notations

Field Attributes

The field definition may have following attributes:

readonly

Calculation of the value of the field is a task of server. Client can not set the value.

writeonly

The server never send the value of the attribute.

immutable

The client may post the value on creating a object, but it can not update the value once the object is created.

Meta Variables

We use the following meta variables in the JSON examples.

$type
Object of type.
$types
Sequence of objects of type. Usually contents of an array.
$base64Encoded
Base64 encoded string of a binary data.
$UUID-like-sequence
String which is expected to be unique in the world. It is UUID in the case the sequence is generated in server. If it is generated by iOS, it is not an exact UUID but an extended one by Apple.
$Time
ISO8601 format string of a time.

Standard Set of APIs on Collections

Most resource collections provides the following set of APIs.

  • Retrieving the collection (Index)
  • Creating or updating items (POST)
  • Optional Retrieving one item (GET)

Standard Index Parameters

Indexing actions take a set of parameters; since, until, and glb. They are used to limit the size of the result sets.

since Limits the result set to contain only updated items since the parameter.
until Limits the result set to reject items updated since the parameter.
glb Greatest lower bound of id of the result set. This is used to retrieve next batch of the collection.
limit

Limits the number of objects contained in the result set.

verbose=true

Retrieve optional information of the resource. You are able to use this parameter in the indexing actions related to Checkout, CheckoutItem, CheckoutPayment, CustomerNote, and MenuItem. Otherwise, the parameter is simply ignored.

image=blob

Retrieve Base64 encoded image if the resource has image data such as receipt_logo and icon. You are able to use this parameter in the actions related to Cashier, CustomerNote, and CustomerTag. Otherwise, the parameter is simply ignored.

total_count=true

Retrieve the number of objects which is actially contained in the result set. By using this parameter, You can know the total count of reccords without reading whole collection.

The result set can be described as follows:

{ item | since ≤ item.updated_at ⋀ item.updated_at < until ⋀ glb < item.id }

The items are sorted by their ids.

The result will be on following pattern.

{
  "timestamp": timestamp,
  "next-url": url,
  "last_updated_at": timestamp,
  rows: [ objects ]
}
timestamp

The timestamp value that it should be passed as a since query parameter in the next batch request. If until parameter is specified, timestamp will be the requested until.

next-url
The URL to retrieve next result set. This will be unspecified in the case there are no more results.
last_updated_at
The timestamp on the time, there were last update of an object which belongs to the resource you requested.
next_batch_since
Deprecated. Use timestamp instead.
$rows

Array of objects. The name will be different, items for MenuItems, categories for Categories, and checkouts for Checkouts.

verbose=true

Retrieve optional information about the resource. You are able to use this parameter in the actions related to Checkout, CheckoutItem, CheckoutPayment, CustomerNote, and MenuItem. Otherwise, the parameter is simply ignored.

image=blob

Retrieve Base64 encoded image if the resource has image data such as receipt_logo and icon. You are able to use this parameter in the actions related to Cashier, CustomerNote, and CustomerTag. Otherwise, the parameter is simply ignored.

Fetching Whole Collection

There are limitation on the number of objects contained in one request; this is the reason we accept glb parameter. You might have a question that how to get the whole collection? A set of requests to fetch collections can be interleaved by requests which updates objects which is contained in the collection. In that case, the updated_at field will be updated and because of the until parameter included in the fetch request, the updated objects can not be fetched.

last_updated_at field is to handle such case. If there are no next-url field sent, which means there are no more object for the parameters you specified, check if the timestamp field is newer than last_updated_at.

  1. Send a request without until and glb parameters.
  2. Check if the response contains next-url field.
  3. If contains, fetch the next-url and go step 2 again.
  4. If not contains, send a request again but with since = timestamp, and go step 2 again.

POST Convention

POST actions to collection create or update more than one items. This helps to make updating many items faster.

The request will be like the following:

[
  { "name": "new object", ... },
  { "name": "another new object", ...},
  { "id": 123, "name": "object to be updated" }
]
  • If there are no id field in an object, it will create new item.
  • If there are id field in an object, it will update an existing item.

The post action is transactional. If there are an error processing an item, all creation or update of items will be canceled. There will be one of everything ok or nothing changed.

There is no limitation on number of objects in one request, but you should take care of it. 100 items in a request will be ok. 10,000 items in a request should cause a problem. We will ask you to stop posting too big request, if there are some problem.

ch1#object-account Account

Account object represents an Ubiregi account. This is one of the most fat object such that it has most related data with the account including tables, cashiers, payment types. Fetching an Account object should be the entry point for most API clients.

Account objects are readonly. There are no API to update.

Fields

id Readonly Immutable
Account ID.
login
Account's login
email
Account's email
name
Account name to be displayed to users.
expire_at
Expiration data. May be `null` in the case there is no expiration on subscription.
currency
One of "JPY", "USD", "Unknown 2", and "Unknown 3".
date_offset
The hour date changes. If this is 6, the date changes at 6 AM, ie 2012-01-01T05:59:00Z is December 31, 2011 (If the timezone is UTC).
timezone
Timezone.
receipt_title
Receipt title.
receipt_footer
Footer text to be printed on receipt.
receipt_logo
Base64 encoded logo image to be printed on receipt.
menus
Array of IDs of Menu.
tables
Array of Tables.
customer_tags
Array of CustomerTags.
payment_types
Array of PaymentTypes.
cashiers
Array of Cashiers.
parent_ids
Array of IDs of parent accounts.
child_ids
Array of IDs of child accounts.
sibling_ids
Array of IDs of sibling accounts.
{
  "id": 123,
  "created_at": "2011-12-31:00:00:31Z",
  "updated_at": "2012-01-30:00:30:11Z",
  "login": "ubiregi-cafe",
  "email": "cafe@ubiregi.com",
  "name": "Ubiregi Cafe",
  "expire_at": "2011-11-13T00:00:00Z",
  "subscription": "trial",
  "currency": "JPY",
  "date_offset": 6,
  "timezone": "Asia/Tokyo",
  "receipt_title": "RECEIPT",
  "receipt_footer": "Footer to be printed in receipts",
  "receipt_logo": $base64Encoded,
  "menus": [ 8 ],
  "tables": [ $tables ],
  "customer_tags": [ $customer_tags ],
  "payment_types": [ $payment_types ],
  "cashiers": [ $cashiers ],
  "parent_ids": [ 100 ],
  "child_ids": [ 200, 124 ],
  "sibling_ids": [ 100, 2031, 581 ]
}

GET on /accounts/account_id

Retrieves an Account object with account_id.

account_id can be either the ID of account or an string "current". If "current" is specified, it is understood as the ID of current account.

Request

GET /accounts/133
GET /accounts/current

Response

{
  "account": $account,
  "timestamp": "2011-11-02T09:11:34Z"
}
account
The account.
timestamp
The time in ubiregi.com server.

Note

The access is only allowed to current, parent, and child accounts. In other case, your request will result in 404 (not found) error.

Table

Table object is deprecated. It is working now but will be obsoleted soon.

Table objects represent tables. Table is special mark for restaurants tables. However, it will be deprecated soon. Using CustomerTag instead of Table is encouraged.

Since it will soon be deprecated, there are no API to update. The only way to edit Table is logging in to the Ubiregi web app.

Retrieving Tables can be done through Account objects.

Fields

id Readonly Immutable
ID of the object.
name
Name of the table.
{
  "id": 123,
  "name": "Table 1"
}

CustomerTag

Tags to give various information on checkouts. This can be used to record that the customer is 20th girl, they came for dating, and so on.

Fields

id Readonly Immutable
ID of the object.
name
Name of the tag.
position
Position of the tag. null in the case the tag is inactive. The interpretation depends on client, however the value should be from 1 to 12. There is no validation on ubiregi.com server on the uniqueness of position.
icon_name Writeonly
Name of icon.
icon Readonly
Icon image for the tag.
icon_mime Readonly
MIME type of the icon. Usually image/png.
{
  "id": 123,
  "name": "Dating",
  "position": null,
  "icon": $base64Encoded,
  "icon_mime": "image/png"
}

Setting an Icon

Icons can be set through icon_name attribute. The value of icon_name should be one of the following list.

*** FIXME ***

Icons are sent from server as its binary image in Base64 encoded form.

Thus, icon_name is a writeonly attribute and icon and icon_mime are readonly attributes.

POST on /accounts/account_id/customer_tags

Update the customertags of an account specified by *accountid*.

Request

{
  "customer_tags": [
    {
      "name": "Dating",
      "position": 10,
      "icon_name": "F1",
    },
    {
      "id": 31,
      "position": null,
    }
  ]
}
customer_tags
Collection of CustomerTag objects.
id
name
position Optional
icon_name

Response

{
  "timestamp": "2011-11-02T09:11:12Z",
  "customer_tags" : $customer_tags
}
timestamp
customer_tags
Collection of updated/created customer tags. Client app should refresh account information to make sure there are no more CustomerTags defined.

Cashier

Cashier object represents the person who operated the cash register.

Fields

id Readonly Immutable
ID of the object.
name
Name of the cashier.
enabled
true if the cashier is enabled. false if the cashier is disabled.
icon
Base64 encoded binary data of icon.
icon_mime Readonly
MIME type of the icon. Usually, "image/png" or "image/jpeg".
{
  "id": 385,
  "name": "Soutaro Matsumoto",
  "enabled": true,
  "icon": $base64Encoded,
  "icon_mime": "image/png"
}

POST on /accounts/account_id/cashiers

Update the cashiers of an account specified by :account_id. The child account's cashiers can be updated by parents.

Request

{
  "cashiers": [
    {
      "name": "New cashier",
      "enabled":true,
      "icon":$base64Encoded
    },
    {
      "id": 1,
      "enabled": false
    }
  ]
}
cashiers
Array of Cashier objects to be updated/created.
id
name
enabled Optional
icon Optional
Base64 encoded data of icon. If unspecified, the icon is not updated. If specified with null, the icon will be removed.

Response

{
  "timestamp": "2011-11-02T09:11:12Z",
  "cashiers" : $cashiers
}
timestamp
cashiers
Array of updated/created Cashiers.

PaymentType

PaymentType represents how the bill is payed by; cash? or credit card?

Fields

id Readonly Immutable
ID of the object.
name
Name of the payment type.
position
Position of the type. null in the case the payment methods is disabled.
change
true if customers will receive change.
kind
One of "cash", "card", or "other". "cash" kind payment type exists in all accounts.
{
  "id": 111,
  "name": "Credit card",
  "position": 3,
  "change": true,
  "kind": "card"
}

POST on /accounts/account_id/payment_types

Change payment type of the account specified by :account_id.

Request

{
  "payment_types": [
    {
      "name": "Book Coupon",
      "enabled":true,
      "change": true,
      "kind": "other"
    },
    {
      "id": 123,
      "change": false
    }
  ]
}
payment_types
Array of PaymentType objects to update/create.
id
name
enabled
change
kind

Response

{
  "timestamp": "2012-02-14T09:00:00Z",
  "payment_types" : $payment_types
}
timestamp
payment_types

Category

Category is set of MenuItems to organize and help user to input checkouts.

Fields

id Readonly Immutable
ID of the object.
name
Name of the item.
position
Position of the category in menu. null if the category is disabled.
{
  "id": 371,
  "name": "Coke",
  "position": 1021
}

GET on /menus/menu_id/categories

Retrieves Categorys defined in menu specified by menu_id.

Request

GET /menus/13/categories?since=2011-01-01T18:00:13Z
since
until
glb

Response

{
  "timestamp": "2012-01-03T03:11:03Z",
  "next-url": "https://ubiregi.com/api/3/menus/13/categories?since=2011-01-01T18:00:13Z&until=2011-01-03T03:11:03Z&glb=13476",
  "last_updated_at": "2012-01-02T21:14:08Z",
  "categories": [ $categories ]
}
timestamp
next-url
last_updated_at
categories

POST on /menus/menu_id/categories

Update/Create the categories of the menu specified by menu_id.

Request

{
  "categories": [
    {
      "name": "Soft drinks",
      "position": 102
    },
    {
      "id": 1022,
      "position": null
    }
  ]
}
items
Array of Category objects to be updated/created.
id
name
position Optional

Response

{
  "timestamp": "2011-11-02T09:11:12Z",
  "categories" : [ $categories ]
}
timestamp
categories

MenuItem

Item in menus, which represents one product/service you sell.

Fields

id Readonly Immutable
ID of the object.
sku Immutable
SKU of the item.
name
Name of the item. variation value is appended unless group parameter is true.
barcode
Barcode of the item.
price_type
Note on price. One of "intax", "outtax", "percentage", and "nosales". "intax" is used for normal items, such that the VAT is included in the price. "outtax" is to mark that the VAT is not included in the price. "percentage" is for discounting/premiums. If "20" is the price of the item and the price_type is "percentage", The price is 20% of premier. "nosales" is mark that the total sales with this item is not included in sales.
price
Price of the item. Note that price is a string to avoid inaccurate computation using floats.
vat
Percentage of VAT in integer. Present if price_type is "intax" or "outtax".
position
Position of the item in its category. null if the item is disabled.
category_id
The category the item is belonging to. null if the item is disabled.
tag_ids
Array of IDs of CustomerTag objects that are related to this item.
stock Readonly
The stocks with respect to StockEvents.
last_inventory_at Readonly
The time at which the most recent inventory was made according to StockEvents.
incoming_stock Readonly
The number of the item which was ordered but not yet arrived.
annotations
Array of annotations associated with the menu item.
group
Group name of the menu item. This field is only returned when group parameter is true.
variation
Variation of the menu item. This field is only returned when group parameter is true.
{
  "id": 271,
  "sku": "sku",
  "name": "Coke",
  "price_type": "intax",
  "price": "105",
  "vat": 5,
  "position": 102,
  "category_id": 105,
  "tag_ids": [ 2001 ],
  "stock": 103,
  "last_inventory_at": "2012-02-13T14:00:31Z",
  "incoming_stock": 13,
  "annotations": []
}

Annotations

MenuItem can be annotated. Annotation is a pair of two strings, name and value. One MenuItem can have several annotations.

To put annotations to a menu item, POST json data with expected annotations.

{
  "id": 271,
  ...
  "annotations": [
    { "name": "name1", "value": "..." },
    { "name": "name2", "value": "..." }
  ]
}

Annotations not included in the POSTed "annotations" array will be removed. If you does not post "annotations" attribute, no annotations will be updated.

rpoint:annotation

MenuItem with the annotation of value "X" will be ignored to calculate number of points for Rpoint card. "X" is the only one value allowed for this annotation.

{ "name": "rpoint:annotation", value: "X" }

Optional Parameters

`MenuItem` may take an optional group parameter.

group Set group=true to include group/variation fields in response.
{
  "id": 271,
  ...
  "group": "Casual wear/T-shurt",
  "variation": "red"
}

GET on /menus/menu_id/items

Retrieves the MenuItems defined in menu specified by menu_id.

Request

GET /menus/13/items?since=2011-01-01T18:00:13Z
GET /menus/13/items?sku=item12345
GET /menus/13/items?id=123
since
until
glb
sku
This parameter is to download a menu item with given sku. Since sku is unique in a menu, one or zero item will be retrieved.
id
This parameter is to download a menu item with given id. Since id is unique in a menu, one or zero item will be retrieved.

Response

{
  "timestamp": "2012-01-03T03:11:03Z",
  "next-url": "https://ubiregi.com/api/3/menus/13/items?since=2011-01-01T18:00:13Z&until=2011-01-03T03:11:03Z&glb=13476",
  "last_updated_at": "2012-01-02T21:14:08Z",
  "items": [ $menu_items ]
}
timestamp
next-url
last_updated_at
items

POST on /menus/menu_id/items

Update/Create the menu item of the menu specified by :menu_id.

Request

{
  "items": [
    {
      "sku": "new_sku",
      "name": "New menu item",
      "price_type":"intax",
      "price": "1000",
      "vat": 5,
      "position": 102,
      "category_id": 105
    },
    {
      "id": 1022,
      "name": "Renamed menu item",
      "price_type":"percentage",
      "price": "1500",
      "position": 103,
    }
  ]
}
items
Array of MenuItem objects to be updated/created.
id
sku
name
price
price_type
vat Optional
position Optional
category_id

Response

{
  "timestamp": "2011-11-02T09:11:12Z",
  "items" : $items
}
timestamp
items

Stock Event

Event object related to stock control. The object is used to tell someone that stock-related event has occured. Type of a stock event is either "inventory", "arrival", "shipping", or "order".

Fields

id Readonly Immutable
ID of the event.
menu_item_id Immutable
ID of the menu item associated with the event.
app_created_at Writeonly Immutable
Time when the event has been created in a client app.
inventory_at Immutable
Time when the inventory event has occured. It maybe different from app_created_at.
event_type Immutable
Type of the event. One of "inventory", "arrival", "shipping", and "order".
amount Immutable
An integer which represents amount of the event
guid Immutable
UUID associated to the event. This is used to prevent duplicated posts.
body Immutable
An arbitrary JSON object. The usage of the value is not decided yet.
deleted
true or false.
checkout_guid
GUID of checkout which is associated with the stock event. null if there is no checkout to be associated with.
{
  "id" : 1,
  "menu_item_id" : 2,
  "app_created_at" : "2012-02-14T00:00:00Z",
  "inventory_at" : "2012-02-14T01:00:00Z",
  "event_type" : "arrival",
  "amount" : 55,
  "guid" : $UUID-like-sequence,
  "body" : { "note" : "This object represents that 55 items specified by `menu_item_id` has arrived" },
  "deleted": false,
  "checkout_guid": $UUID-like-sequence
}

Amount of an Event

The interpretation of amount depends on the event's event_type.

Assume there is a StockEvent object with amount = 55. It says the following facts depending on event_type:

"inventory"
The current stock of the menu is 55.
"arrival"
The number of the items arrived is 55.
"shipping"
The number of the item shipped is 55.
"order"
The number of the item someone ordered is 55.

GET on /accounts/account_id/stocks/events

Request

GET /accounts/current/stocks/events?since=...
since
until
glb

Response

{
  "timestamp": "2011-11-02T09:11:34Z",
  "next-url": "https://ubiregi.com/api/3/accounts/1032/stocks/events?since=.....",
  "last_updated_at": "2011-12-31T00:00:31Z",
  "events": [ $stock_events ]
}
timestamp
next-url
last_updated_at
events

POST on /accounts/account_id/stocks/events

Create StockEvent objects of Account specified by account_id. Since there is no mutable field in StockEvent, it is impossible to update.

Request

{
  "events": [
    {
      "menu_item_id" : 21,
      "app_created_at" : "2012-02-14T00:00:00Z",
      "inventory_at" : "2012-02-14T01:00:00Z",
      "event_type" : "arrival",
      "amount" : 55,
      "guid" : $UUID-like-sequence,
      "body" : {
        "author": "Soutaro Matsumoto"
      },
      "deleted": false,
      "checkout_guid": null
    }
  ]
}
events
Array of StockEvents objects which will be created.
menu_item_id
app_created_at
inventory_at
event_type
amount
guid
body Optional
deleted Optional
If there is not deleted in the request, it will be treated as if false is specified.
checkoug_guid Optional

Response

{
  "timestamp": "2012-02-14T09:00:00Z",
  "events" : [ $stock_events ]
}
timestamp
notes

Checkout

Checkout object represents an checkout/bill.

Fields

id Readonly Immutable
ID of the object
guid Immutable
UUID of checkout. The ID is generated by clients, thus it may not be unique. This is used to prevent a checkout posted from being inserted more than one time. The tuple of guid, paid_at, and account_id is used to identify a checkout.
account_id Immutable
ID of account which the checkout is belonging to.
paid_at
Record when the bill is paid at.
sales_date Readonly
The date for paid_at with respect to its account's timezone and date_offset. (The example here assumes account's timezone is "Asia/Tokyo" and date_offset is 0.)
price Readonly
A string which represents server's calculated total sales of the checkout.
change
A string which represents change given to the customer.
status
The status of the checkout. One of "close", "open", "deleted", or "cancel". "close" is for closed checkout, such that the cashier already finished editing the checkout. "open" is for open checkout, such that the cashier is continuing editing the checkout. "cancel" is for deleted checkout, such that the checkout once was closed, but later canceled. "deleted" is for canceled checkout, such that the checkout was deleted without closing it.
cashier_id
ID of the cashier who processed the checkout. May be null if input skipped.
customers_count
Number of customers associated with the checkout. Zero in the case omitted.
payments
Array of CheckoutPayment, which describes how the checkout is got paid.
taxes
Array of CheckoutTax, which describes taxes included or added to the checkout.
items
Array of CheckoutItem, which describes which items are sold.
table_ids
Array of ID of Table.
customer_tag_ids
Array of ID of CustomerTags.
modifier Readonly
Only for compatibility.
calculation_option
Calculation option which is used to calculate this checkout's price and tax.
  • tax_rounding_mode: "plain"(default), "down" or "up"
  • price_rounding_mode: "plain"(default), "down" or "up"
  • tax_calculation_level: "checkout_item"(default) or "checkout"
rpoint_transaction Immutable
RpointTansaction associated with the checkout.
{
  "id": 1,
  "guid": "8928309238-d987aerkeh-9847tdfkzhg4",
  "account_id": 1,
  "paid_at": "2011-12-24T16:20:20Z",
  "sales_date": "2011-12-25",
  "price": "385.0",
  "change": "4000.0",
  "status": "close",
  "cashier_id": null,
  "customers_count": 0,
  "payments": [ $Payments ],
  "taxes": [ $CheckoutTaxes ],
  "items": [ $CheckoutItems ],
  "table_ids": [ 99, 8 ],
  "customer_tag_ids": [ 10, 1003 ],
  "modifier": "0.0",
  "calculation_option": {
    "tax_rounding_mode": "down",
    "price_rounding_mode": "plain",
    "tax_calculation_level": "checkout"
  }
}

GET on /accounts/account_id/checkouts

Retrieves the checkouts of the account which specified with account_id. The account should be one of current account, parent, children, or siblings. In other case, the request will result in 404 not found.

Request

GET /accounts/current/checkouts
GET /accounts/113/checkouts?since=....
since
until
glb

Response

{
  "timestamp": "2011-11-02T09:11:34Z",
  "next-url": "https://ubiregi.com/api/3/accounts/31/checkouts?since=.....",
  "last_updated_at": "2011-12-31T00:00:31Z",
  "checkouts": [ $checkouts ]
}
timestamp
next-url
last_updated_at
checkouts
Array of Checkouts for the request.

GET on /accounts/account_id/checkouts/close

Retrieves the closed checkouts of the account which specified with account_id. Checkout which status is "close" or "cancel" is closed checkout.

Request

GET /accounts/current/checkouts/close
GET /accounts/113/checkouts/close?since=....
since
until
glb

Response

{
  "timestamp": "2011-11-02T09:11:34Z",
  "next-url": "https://ubiregi.com/api/3/accounts/31/checkouts/close?since=.....",
  "last_updated_at": "2011-12-31T00:00:31Z",
  "checkouts": [ $checkouts ]
}
timestamp
next-url
last_updated_at
The latest closed checkout updated_at.
checkouts
Array of Checkouts for the request.

POST on /accounts/account_id/checkouts

Create/update checkout of account with account_id.

Checkouts of current account and its child accounts are writable. Otherwise, the post request to checkouts will result in 400 error.

Request

{
  "checkouts": [
    {
      "items": [
        {
          "menu_item_id": 123,
          "count": 1,
          "sales": "100",
          "tax": "5",
          "discount_sales": "20",
          "discount_tax": "1"
        }
      ],
      "change" : "26",
      "guid" : $UUID-like-sequence,
      "paid_at": $Time,
      "payments": [
        { "payment_type_id": 101, "amount": "100" }
      ],
      "customers_count': 1,
      "customer_tag_ids': [ 20 ],
      "cashier_id": 948,
      "status": "Open"
    },
    {
      "id": 4739,
      "status": "Close"
    }
  ]
}
checkouts
Checkout objects to be created/updated.
id
guid Optional
change
status
cashier_id Optional
customers_count
paid_at
payments
Array of CheckoutPayments.
items
Array of CheckoutItems.
table_ids
Array of IDs of Tables.
customer_tag_ids
Array of IDs of CustomerTags.

There are validations on creating checkout objects. It should be good practice to send all attributes when creating new checkout.

Updating items and payments

{
  "checkouts": [
    {
      "id": 123
      "payments": [
        {
          "payment_type_id": 13,
          "amount": "1032"
        },
        {
          "id": 3112,
          "amount": "809"
        }
      ],
      "items": []
    }
  ]
}
Creating an Object

Include an object without id. The first payments object is creating an CheckoutPayment.

Updating an Object

Include an object with id and updating attributes. The second payments object is updating amount of a CheckoutPayment with its ID is 3112.

Deleting an Object

Objects which is not included in the array are deleted. All objects in items will be deleted.

Response

{
  "timestamp": "2011-11-02T09:11:34Z",
  "checkouts": [ $checkouts ]
}
timestamp
checkouts

CheckoutItem

CheckoutItem object represents each sold menu item in a checkout. It records how many the item sold and the price.

Fields

id Readonly Immutable
ID of the object
menu_item_id
ID of the menu item
count
The number of the items the customer bought. May be negative to express a return.
sales
Sales amount without TAX.
tax
TAX for the item.
discount_sales
Sales discounted
discount_tax
TAX discounted
guid Immutable
UUID like sequence
{
  "id": 1,
  "menu_item_id": 1,
  "count": 3,
  "sales": "330.0",
  "tax": "0.0",
  "discount_sales": "0.0",
  "discount_tax": "0.0",
  "guid" : $UUID-like-sequence
}

Notes

Make sure the amounts of currency; sales, tax, discount_sales, and discount_tax; are represented as a string, not a number. The price is calculated as follows: sales + tax - (discount_sales + discount_tax).

CheckoutTax

Tax rate and amount which are included or added to the checkout.

Fields

id Readonly Immutable
ID of the object
tax_rate
Tax rate
guid Immutable
UUID like sequence
tax
Calculated tax amount
sales
Sales amount which is subjected to this tax
discount
Discounted amount which is subtracted from sales before calculation of tax
tax_type
One of "included" or "excluded"
{
  "id": 1,
  "tax_rate": "8.0",
  "tax_type": "included",
  "sales": "100.0",
  "tax": "7.0",
  "discount": "0.0",
  "guid" : $UUID-like-sequence
}

Notes

Make sure numerical value is a string.

CheckoutPayment

Pair of amount the customer paid, and method the payment maid with.

Fields

id Readonly Immutable
ID of the object
payment_type_id
ID of PaymentType
amount
An string which represents the amount customer paid
guid Immutable
UUID like sequence
{
  "id": 1,
  "payment_type_id": 1,
  "amount": "5000.0",
  "guid" : $UUID-like-sequence
}

Notes

Make sure amount value is a string.

Customer

Customer object represents a customer, which can be used in Customer Relation Management.

Fields

id Readonly Immutable
ID of the object
account_id Readonly Immutable
ID of account which this customer is associated with
fields
Array of CustomerField object. fields can not be empty.
guid Immutable
An GUID which uniquely identifies the customer. The GUID is generated in client side, a client should be careful to read it unique.
deleted
true if and only if the customer is deleted.
{
  "id": 100,
  "account_id": 2,
  "fields": [ $customer_fields ],
  "guid": $UUID-like-sequence,
  "deleted": true
}

GET on /customers

Retrieve collection of customers available for the account.

Request

GET /customers?since=...
since
until
glb

Response

{
  "timestamp": "2011-11-02T09:11:34Z",
  "next-url": "https://ubiregi.com/api/3/customers?since=.....",
  "last_updated_at": "2011-12-31T00:00:31Z",
  "customers": [ $customers ]
}
timestamp
next-url
last_updated_at
customers

Available Customers

An customer is available only if the customer is associated with one of the following:

  1. Current account's parents
  2. Current account's children
  3. Current account's siblings

The circles represent accounts and gray arrows represents parent-child associations. Accounts covered with purple background are accessible accounts, so that their accounts are available to current account (the red one).

POST on /customers

Create an Customer objects, or update Customer objects available for current account.

Request

{
  "customers": [
    {
      "guid": $UUID-like-sequence,
      "deleted": false,
      "updated_fields": [ $customer_fields ]
    }
  ]
}
customers
Array of Customer objects which will be updated/created.
guid Optional
deleted
updated_fields Optional
Array of updated or newly inserted CustomerFields.

Response

{
  "timestamp": "2012-02-14T09:00:00Z",
  "customers" : [ $customers ]
}
timestamp
customers

updated_fields

It is not allowed to destroy CustomerFields. Thus, fields attribute in POST requests are not defined, but updated_fields should be used instead. To (logically) destroy CustomerFields, set its deleted field to true.

CustomerField

A customer field belongs to a customer. This is mainly used to be included in a customer object.

Fields

id Readonly Immutable
ID of the object.
guid Immutable
GUID.
app_created_at Writeonly Immutable
Time when the field has been created in a client app.
name Immutable
Name of the field.
value Immutable
Value in string of the field
deleted
{
  "id": 1345,
  "guid": $UUID-like-sequence,
  "app_created_at": "2012-02-14T00:00:00Z",
  "name": "customer.field.name",
  "value": "Ubiregi Taro",
  "deleted": false
}

Customer Attributes

Field Name
Description
"customer.field.customerID"
Arbitary customer ID. The interpretation depends on the client.
"customer.field.name"
Name of the customer.
"customer.field.ruby"
Ruby of the name.
"customer.field.birthday"
Birthday. The birthday value is expected to be formatted in YYYY-MM-DD, where YYYY is year in 4 digits, MM is month in 2 digits, and DD is day in 2 digits.
"customer.field.sex"
Sex of the customer. The value is expected to be one of "F" and "M", for female and male, respectively.
"customer.field.email"
Email address of the customer.
"customer.field.phone"
Phone number of the customer.
"customer.field.twitter"
Twitter ID of the customer, without @.
"customer.field.zip"
Zip code of the customer.
"customer.field.address1"
"customer.field.address2"
Address of the customer. address1 is expected to be an address. address2 is expected to be additional information, like room number or building number.

Updating CustomerField

Updating value of a CustomerField object is not recommended. Just create new field, and delete it (set deleted).

This is to avoid conflicting changes in two places, for example in your app and in the Ubiregi iPad app. If you do not update an existing CustomerField, the conflict will result in duplicated fields, and user can choose one, and then delete the other. This is safe.

CustomerNote

A customer note belongs to a customer.

Fields

id Readonly Immutable
ID of this object.
customer_id Immutable
ID which their object belongs to.
app_created_at Writeonly Immutable
Time when the note is created in a client app
guid Immutable
GUID
checkout_id Immutable
ID of Checkout object, which the note is associated with.
kind
"icon" or null. "icon" in the case the photo is icon of the customer.
note
Comment.
photo
Base64 encoded photo data, resized to 256px x 256px (for thumbnail).
photo_url Readonly
URL of full size photo. May be absent. (we are working for this.)
{
  "id": 1,
  "customer_id": 1,
  "app_created_at": "2012-02-14T00:00:00Z",
  "guid": $UUID-like-sequence,
  "checkout_id": 2,
  "kind": "icon",
  "note": "Memo Memo",
  "photo": $base64Encoded,
  "checkout_summary": "Summary"
}

Note on Photo

Writing Photo    When you are uploading CustomerNote, photo data is expected to be full size photo data.

Reading Photo    When you are downloading CustomerNote, photo attribute is thumbnail generated in ubiregi.com server. The thumbnail is 256px x 256px size, JPEG data. The size should be convenient for many cases in your app to show a thumbnail to users. In the case you really need full size data, access the photo_url and download it.

GET on /customers/notes

Request

GET /customers/notes?since=...
since
until
glb

Response

{
  "timestamp": "2011-11-02T09:11:34Z",
  "next-url": "https://ubiregi.com/api/3/customers?since=.....",
  "last_updated_at": "2011-12-31T00:00:31Z",
  "notes": [ $customer_notes ]
}
timestamp
next-url
last_updated_at
notes

Available CustomerNotes

A CustomerNote is available only if the note is associated with available Customer.

POST on /customers/notes

Create a CustomerNote objects, or update CustomerNote objects available for current account.

Request

{
  "notes": [
    {
      "id": 1,
      "customer_id": 1,
      "app_created_at": "2012-02-14T00:00:00Z",
      "guid": $UUID-like-sequence,
      "checkout_id": 2,
      "kind": "icon",
      "note": "Memo Memo",
      "photo": $base64Encoded,
      "checkout_summary": "Summary"
    }
  ]
}
notes
Array of CustomerNote objects which will be updated/created.
id
customer_id
Customer for the customer_id should be available from current account.
app_created_at
guid Optional
checkout_id Optional
Should be ID of Checkout of current account.
kind Optional
note Optional
photo Optional
checkout_summary Optional

Response

{
  "timestamp": "2012-02-14T09:00:00Z",
  "notes" : [ $customer_notes ]
}
timestamp
notes

Paid In/Out

PaidInOut object represents paid in and paid out to/from the cash register.

Fields

id Readonly Immutable
ID of the object.
amount
Amount of the paid in/out. It's a positive number if paid in, a negative number if paid out.
title
Title of the paid in/out.
account_id Immutable
ID of account which the paid in/out is belonging to.
guid Immutable
An GUID which uniquely identifies the paid in/out. The GUID is generated in client side, a client should be careful to read it unique.
device_id
GUID of device which recorded by.
recorded_by_id
ID of the cashier who recorded paid in/out.
canceled_by_id
ID of the cashier who canceled paid in/out.
recorded_at
Time for recorded at this paid in/out.
canceled_at
Time for canceled at this paid in/out.
{
  "id": 856,
  "amount": "-123450.0",
  "title": "Bank payment",
  "account": 385,
  "guid": "B15C25EB-32DF-435A-A010-50601BB444AA",
  "device_id": "25D21F84-66F4-4197-B89C-D09470EB27E8",
  "recorded_by_id: 231,
  "canceled_by_id: 232,
  "recorded_at": "2015-12-02T13:21:12Z",
  "canceled_at": "2015-12-02T14:01:23Z"
}

GET on /accounts/account_id/paid_inouts

Retrieves the PaidInOuts of an account specified by account_id.

Request

GET /accounts/current/paid_inouts
GET /accounts/113/paid_inouts?since=2015-01-01T18:00:13Z
since
until

Response

{
  "timestamp": "2015-01-03T03:11:03Z",
  "next-url": "https://ubiregi.com/api/3/accounts/113/items?since=2015-01-01T18:00:13Z&until=2015-01-03T03:11:03Z&glb=13476",
  "last_updated_at": "2015-01-02T21:14:08Z",
  "paid_inouts": [ $paid_inouts ]
}
timestamp
next-url
last_updated_at
paid_inouts

POST on /accounts/account_id/paid_inouts

Create a PaidInOut objects, or update PaidInOut objects of the account specified by :account_id.

Request

{
  "paid_inouts": [
    {
      "guid": "59516b4e-9d8f-11e5-9d2e-c3f422ef8fcf",
      "amount": "-123450.0",
      "title": "Bank payment",
      "device_id": "710b52d6-9d8f-11e5-9aac-af957c6aaf43",
      "recorded_by_id": 231,
      "recorded_at":  "2015-12-02T13:21:12Z"
    },
    {
      "id": 857,
      "canceled_by_id: 232,
      "canceled_at": "2015-12-02T14:01:23Z"
    }
  ]
}
paid_inouts
Array of PaidInOut objects to be updated/created.
id
guid
amount
title
device_id
recorded_by_id
canceled_by_id
recorded_at
canceled_at

Response

{
  "timestamp": "2015-12-02T14:11:12Z",
  "paid_inouts" : $paid_inouts
}
timestamp
paid_inouts
Array of updated/created PaidInOuts.

RpointTransaction

Fields

guid Immutable
card_id Immutable
use_amount Immutable
Number of points used for the checkout.
checkout_guid Immutable
canceled_at
ISO8061 string or null when the transaction is not canceled.
items
Array of RpointTransactionItem.
{
  "guid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
  "card_id": "1234-5678-9012-3456",
  "use_amount": 10,
  "checkout_guid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
  "canceled_at": null,
  "items": [ ... ]
}

RpointTransactionItem

Fields

kind Immutable
One of the values of RpointKind.
amount Immutable
Number of points issued to the customer.
item_id Immutable
ID of RpointItem for the item, or null.
price Immutable
{
  "kind": "const10",
  "amount": 10,
  "item_id": 123,
  "price": null
}
{
  "kind": "default",
  "amount": 11,
  "item_id": null,
  "price": 1105
}

Note

kind item price
"default" null Price which is used to calculate value of amount
* Object representing RpointItem null

RpointItem

Fields

id
name
kind
display_name
note
default_item
position
null if the item is hidden.
{
  "id": 123,
  "name": "MyCampaign",
  "kind": "const10",
  "display_name": "...",
  "note": "...",
  "default_item": false,
  "position": 1,
  "updated_at": "...",
  "created_at": "..."
}

GET on /accounts/account_id/rpoint/items

RpointKind

  • "default"
  • "const10"
  • "const50"
  • "const100"
  • "const500"
  • "percentage1"
  • "percentage2"
  • "percentage4"
  • "percentage9"

API Notes

IDs are Universal

There are only one scope of ID, Universal.

If this doc says ID, it is an one origin integer value which uniquely determines an object on ubiregi server.

Special Fields

Most objects have special fields, created_at and updated_at.

created_at Readonly
Server time at which the object is created.
updated_at Readonly
Server time at which the object is updated.

Permissions on Objects of Other Accounts

Ubiregi API permission model is very simple. The permission to a object is decided by its owner account's role.

There are three permissions, nothing, readonly and writable.

nothing
Any access will be rejected.
readonly
Reading is allowed, but can not update.
writable
Full access allowed.

There are five roles, current, children, parents, siblings, and others.

current
The account which is authenticated.
children
Children of current account.
parents
The accounts of which the current account is a child.
siblings
The accounts which shares parents with current account.
others
Accounts which is not current, children, parents, and siblings.

The permission is defined as following:

readonly
Parents' and siblings' information, menus, checkouts, and stock events.
writable
Current's and children information, menus, checkouts, and stock events.
nothing
Anything else.

and it is figured out as following.

Each circle represents an Account. Gray arrows represent parent-child links between accounts. Red, green, blue, purple, and gray circles represent current, children, parents, siblings, and others accounts respectively. Green background is for the object which owns objects with writable permission, and light-pink background is for readonly permission.

Note that Customers have their own permission model.

Stock Calculation Model

Each MenuItem has its own stock count. stock, last_inventory_at, and incoming_stock are updated when new StockEvent is created.

last_inventory_at
Find the latest inventory event, and set its inventory_at.
stock
Find the latest_inventory_event and its following_events, and calculate the following:
last_inventory_amount - shipped_amount + arrived_amount
where:
last_inventory_amount = latest_inventory_event.amount
shipped_amount = Σ following_shipping_events.amount
arrived_amount = Σ arrival_events.amount
incoming_stock
Calculate all order_events and arrival_events, and calculate the following:
Σ order_events.amount - Σ arrival_events.amount

app_created_at Usage

app_created_at field is to remember when the object is created in the iPad app. It generally meaningless; iPad clock may be inaccurate, the clock can easily changed.

It is recommended to record some time, or just use the time of post.

Private Fields

There may be private fields, not defined in this document but you find in the response from server. It is okay if you use these fields, but keep in your mind they are private so that it may be removed without any announcement.

Downloading Images

Image fields including icon and photo are null by default. This is to reduce the size of data transmission.

To download the image data, give an http query parameter image=blob.

Example: Downloading with Icons

GET /accounts/current?image=blob

GET /accounts/customer/notes?image=blob

Errors

Errors are notified via HTTP response status. Error code are following the standard HTTP error code convention. If there are something bad in your request, you will get 4xx. If there are something wrong happen on the server, you will get 5xx.

Status code

We define following status codes, where the meaning is shared between all requests.

304 (Not Modified)
This is not an error. This means there are no updates to the resources requested since last request. This status is only returned when you specify If-Modified-Since HTTP header with the same value as since parameter in request JSON.
400 (Bad Request)
Something is wrong with the request you've sent. Please read the document carefully. Response message might be a help.
401 (Unauthorized)
The request does not contains valid authentication token for your application.
402 (Payment Required)
API is only accessible to paid users.
403 (Forbidden)
Your request is rejected by the server. For example, if you modify read-only attribute, status code 403 is returned.
404 (Not Found)
Resources client want to require is not found. If the status code is 404, we recommend you to check account id, menu id, customer id, and so on in request JSON.
423 (Locked)
Other request is currently updating requested resource. Try again later.
500 (Internal Server Error)
Something is wrong with the server program. Please contact us if you consistently get this error.
503 (Service Unavailable)
Server is under heavy traffic or is under maintenance. Please try again later.

Error object

The error response contains JSON object which represents the detail of the error. The format of Error object is as the followings:

Fields

errors Readonly
Array of an object.
object Readonly
A JSON object included in request JSON that related to the reason why this request failed.
messages Readonly
An array of error messages.
timestamp Readonly
The server time that a request failed.
{
  "errors": [
    {
      "object" : {
        "name": "Existing Cashier",
        "enabled":true,
        "icon":"hogehoge"
      },
      "messages": ["invalid icon"]
    }
  ],
  "timestamp": "2012-03-11T09:00:00Z"
}