Ruby client
This client is for a Ruby backend (Rails, Sinatra, a background job) that would rather not
hand-roll Net::HTTP calls. The meisei gem covers the admin API and the widget API, and is
generated from the same OpenAPI documents this reference is built from, so it never drifts
from what the API accepts. It has no dependencies beyond the standard library and needs Ruby
3.2 or later.
Every Ruby example in this reference uses it.
Install

The admin API
Build a client with a secret key and your store's base URL (see Your base URL). Keep it on your server. A secret key that reaches a browser has leaked. One client is safe to share between threads, so a Rails app can build it once in an initializer.
Leave both arguments out and the client reads MEISEI_SECRET_KEY and MEISEI_BASE_URL
from the environment. An app installed through OAuth passes
access_token: instead of secret_key:.
Calling an endpoint
Endpoints are grouped the way their paths are. The usual five are list, retrieve,
create, update and delete, and anything else is named for what it does:
The reference shows the Ruby call for every endpoint. Path parameters are positional, in the order the path names them. Everything else, query parameters and body fields alike, is a keyword argument in snake_case. The gem sends each one where it belongs, under the API's own name.
Sending nil sends null, which clears a field that can be cleared. Leaving a keyword out
leaves the field as it is. A keyword the endpoint does not take, or a required one you left
out, raises an ArgumentError before anything is sent, with a suggestion for a likely typo.
A few values are converted for you:
- A list for a comma-separated parameter:
include: [:orders_count, :tags]. - A hash for
filter, which is sent as its JSON document. See Filtering. - A sort order or an
includevalue in snake_case:sort: "-created_at". - A
Timeor aDate, which is sent as ISO 8601.
The keys of a hash you send are left alone wherever they are yours, such as metadata, so
metadata: { "giftWrap" => true } arrives exactly as written.
Reading a response
A record comes back as an object with a reader for each field, in snake_case. The records
this reference names (a review, a product, a customer) have their own classes, such as
Meisei::Review, and nested records are wrapped the same way.
A field added to the API after your version of the gem still reads the same way, so you only need to upgrade for new endpoints. Records also work with pattern matching:
Lists and pagination
A list comes back as a page, which is Enumerable over its records. auto_paging_each keeps
fetching pages with the same parameters until the last one, so a whole collection is one loop:
Without a block, auto_paging_each is lazy: auto_paging_each.first(10) stops fetching once
it has ten. See Pagination for how cursors behave.
Errors
A failed request raises. Every error the gem raises is a Meisei::Error, and every
answer from the API that is an error is a Meisei::APIError carrying status,
code and message (see Errors for the codes):
Retries and timeouts
The client retries a rate-limited request after the Retry-After interval the API gives it.
It also retries a 5xx or a dropped connection, with a short backoff, but only on GET,
PUT and DELETE, so a POST is never sent twice. Two retries is the default.
Any call can override these for itself with request_options:, which also takes extra
headers::
The widget API
Meisei::WidgetClient calls the widget API. From a server, give it a secret key. It
reads what the publishable key reads, and draws on your organization's
API allowance rather than one shopper's. See
Calling the widget API from a server.
A publishable_key: works in place of the secret key, for code that runs where a secret key
must not.
Identifying the shopper
Anything personal, such as a shopper's wishlists or loyalty balance, needs their signed email.
Pass customer: and the client does the rest. Give the client your widget signing secret
and customer: takes the email itself:
To keep the signing secret out of your own code, ask the admin API to sign instead, and pass
what it returns. The key needs the customers:write permission.
Meisei.sign_customer signs an email locally, which is also how to hand a signature
to a page so the storefront widgets can identify the shopper. See
Identifying the customer.
Talking to several organizations
A client holds one key and one base URL, so build one per organization. If you are building
an application many merchants install, use OAuth rather than asking each of them for a secret
key, and pass each one's token as access_token:. See
Authentication.