Ruby
The Ruby SDK is an idiomatic gem emitted from the same GlottoIR as every other target. It uses
snake_case methods, keyword args, immutable Data.define models with from_json, and YARD doc
comments generated from the operation prose in the spec.
Manual pages expose items, response metadata and explicit next_page navigation. Per-call request_options: controls headers, deadlines, retries, extra parameters and cancellation. Binary operations return an owned BinaryDownload with bounded read_all, pipe, response metadata and close; block iteration releases the response on break or error. See pagination, request retries and controls, streaming, and file transfers.
Quickstart
gem install petstore
require 'petstore'
client = Petstore::Client.new(token: '<token>')
result = client.pets.get(pet_id: '...')
puts result
Resource objects
Operations are methods on resource objects — client.pets.get(id), client.pets.photos.add(...) —
the Stripe-Ruby service-accessor shape, rather than flat methods on Client.
Persistent connections
Requests reuse a persistent per-host connection (via net-http-persistent) instead of opening a
fresh socket per call, so throughput holds up under load and across threads.
Typed errors
Non-2xx responses raise ApiError, a StandardError hierarchy carrying the parsed, typed error
body, so you rescue RateLimitError rather than inspecting status codes. Discriminated-union
bodies resolve to the right variant. See Errors.
Pagination
List methods return an Enumerator that walks every page lazily, advancing the cursor for you.
See Pagination.
Retries & backoff
Transient failures (5xx, 429, transport errors) retry with exponential backoff and jitter,
configurable per client. See Retries & timeouts, Streaming,
and Authentication.
Unknown response fields
Your API can add a response field without it being a breaking change — but a generated Data class has only the members it declares, and its from_json factory reads only those. The generated
models keep it instead: a field the SDK wasn’t generated from is retained on decode, readable
through an accessor, and written back out when the model is re-serialized.
pet = client.pets.create_pet(body)
# A field your API started returning after this SDK was generated.
species = pet.extra_fields["species"]
# Re-encoding preserves it — a read-modify-write never silently drops it.
json = JSON.generate(pet.to_h)
extra_fields returns a frozen Hash, so nested objects and arrays survive intact, and retention
is recursive.
Use pet.with(name: "Rex") to create an updated immutable value. The copy keeps unknown
response fields and retained timestamps for members you did not change. Replacing a timestamp
explicitly replaces its retained wire value too.
If a declared member already uses with, the copy helper uses the first free name starting
with with_2, preserving the member’s reader.
The retained fields are held in an instance variable rather than as a Data member, so
members, inspect, == and pattern matching on your models are all unchanged — and both
Pet.new(id: …) and Pet.new('p1', …) still work.
The retained fields are read-only by design. To send a field your spec doesn’t model yet, use the per-call extra-body escape hatch rather than writing to the retained bag.