Ruby Sinatra API
A Sinatra API serves a small todo list with routes for health, runtime details, reads, and writes. Tokay runs the Ruby app with Puma as one Web Service.
Last updated
Choose this example when you want the shortest route from a Ruby file and Gemfile to a public API. Your app stays ordinary Sinatra code while Tokay handles its service setup.
- Runtime
- Ruby
- Framework
- Sinatra
- Service types
- Web Service
- Resources
- None
- Required secrets
- None
What it does
Visit the root route to see the Ruby version behind your live service.
The /todos route lists three starting items. Post a JSON title to add another. Bad JSON or an empty title returns a 400 response instead of changing the list.
The /health route confirms that Puma and the app are responding.
Deploy it
Bring this folder to Tokay any way you like. Paste or upload it in the dashboard, push it with git, or hand it to your AI agent along with our agent instructions. Tokay figures out the rest.
Working in Claude, ChatGPT, VS Code, or another MCP client? Connect the Tokay MCP server and ask your agent to deploy this example. It signs in through your browser, so there is no token to paste.
New to Tokay? The getting started guide walks you through your first deploy.
Try it
Use your live URL to add a todo and read it back.
export APP_URL="https://your-app.tokay.app"
curl -X POST "$APP_URL/todos" \
-H 'Content-Type: application/json' \
-d '{"title":"ship the next thing"}'
curl "$APP_URL/todos"
You will find the new item in the second response. Deploy once more and the original three return because the example keeps its list in memory.
How it works
You can keep Sinatra's small route based structure. Tokay installs the gems, provides PORT, and starts Puma with the same app.rb you run locally.
Secrets
No private values are needed. The full API works as soon as the service is live.
Grow from here
Browse the Tokay examples catalog when you want saved data or scheduled work.
Source code
Gemfile Raw
source "https://rubygems.org"
ruby "~> 4.0"
gem "puma", "~> 7.0"
gem "rackup", "~> 2.2"
gem "sinatra", "~> 4.2"
app.rb Raw
require "json"
require "sinatra"
set :bind, "0.0.0.0"
set :port, ENV.fetch("PORT", "3000")
set :server, :puma
TODOS = [
{ id: 1, title: "deploy this ✓" },
{ id: 2, title: "add a database" },
{ id: 3, title: "tell a friend" }
]
before do
content_type :json
end
get "/" do
{
message: "Hello from Sinatra",
runtime: "Ruby #{RUBY_VERSION}"
}.to_json
end
get "/health" do
{ ok: true }.to_json
end
get "/todos" do
TODOS.to_json
end
post "/todos" do
input = JSON.parse(request.body.read)
title = input.is_a?(Hash) ? input.fetch("title", "").to_s.strip : ""
halt 400, { error: "title is required" }.to_json if title.empty?
todo = { id: (TODOS.last&.fetch(:id, 0) || 0) + 1, title: title }
TODOS << todo
status 201
todo.to_json
rescue JSON::ParserError
halt 400, { error: "send a JSON title" }.to_json
end
Built from revision 52c7b7f