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.

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

Guide: Deploy a web app