The Hosted Service
Push, prove, publish and run blueprints on Reason Me This with the same CLI loop, the same JSON and the same exit codes.
After reading this guide, you will know:
- How to point the CLI at the hosted service.
- How
push,publish,run,listandpullmap onto the local loop. - How definitions on a service import one another by name and version.
- What a service will not load.
Why a Service
Locally, a blueprint is a file you check, test and run. On the service, it is a definition: a draft
you push, numbered versions you publish, and a JSON API applications call. The service checks every
draft and runs its cases as check and test do, and refuses to publish one that has problems or a
failing case.
Pointing the CLI at It
export RMT_API_KEY=... # create one at https://reason-me-this.com/app/api_keys
With a key set, the service commands talk to https://reason-me-this.com/api. Set RMT_API_URL to
use another service, such as a local one (http://localhost:3000/api).
A BLUEPRINT ending in .yml or .yaml or containing a / is a file; anything else names a definition
on the service. So rmt run bill.yml runs a file, and rmt run bill runs the published
definition.
The Loop
- Build and prove the blueprint locally with
checkandtest. rmt push NAME BLUEPRINT CASESsaves it as the draft of NAME. The service checks it and runs the cases, answering ascheckandtestdo, with the same exit codes.rmt publish NAMEmakes the draft the next version. A draft with problems or a failing case is refused.rmt run NAME --facts FACTS.jsonruns the latest version;--version drafttries the draft, and--version 3version 3.rmt listandrmt pull NAMEshow what is there.
$ rmt push bill bill.yml cases.yml
✓ 7 cases passed
$ rmt publish bill
✓ Published bill v1
$ rmt run bill --facts facts.json
days 1
usage_charge 1.2
feed_in_credit 0
supply_charge 1.1
total 2.3
$ rmt list
NAME PUBLISHED UPDATED
bill v2 2026-11-04
That is the shipped electricity_bill pushed as bill. A failing case is reported as test reports
it, and the draft is still saved:
$ rmt push bill bill.yml failing.yml
✗ 1 of 7 cases failed
✗ one day on the flat rate is the kWh used at 30c plus the $1.10 daily supply
total: expected 2.5, got 2.3
$ echo $?
3
pull writes a definition’s draft to DIR/NAME/blueprint.yml and cases.yml, and refuses to overwrite
files:
$ rmt pull bill --dir pulled
Wrote pulled/bill/blueprint.yml
Wrote pulled/bill/cases.yml
Exit Codes
The service commands answer with the same codes as their local counterparts, plus two:
| Exit | Means |
|---|---|
| 0 | success |
| 1 | the run failed or the facts do not match the inputs |
| 2 | the draft has problems |
| 3 | a case failed |
| 64 | usage, or no RMT_API_KEY for a command that needs the service |
| 69 | the service could not be reached |
| 77 | the service refused the key |
$ RMT_API_KEY=wrong rmt list
✗ unauthorized
$ echo $?
77
Imports by Name and Version
A service loads a blueprint from its text alone, so a definition imports others by name, never by path:
| Import | Resolves to |
|---|---|
rates |
the latest published version of the workspace’s rates |
rates@3 |
version 3 |
rates@draft |
its draft |
| a name the workspace does not have | a shipped blueprint, such as electricity_bill |
An unpinned import follows the latest version when the definition runs, so publishing a new rates
changes every definition that imports rates unpinned. Pin the version of anything an application relies
on.
A path import is refused: imports ../rates.yml by path, which a blueprint loaded from text cannot.
What a Service Will Not Load
- Custom steps. A workspace never brings Ruby. Steps beyond the built-in ones come only from packs installed with the service.
- Paths. Imports resolve by name to the workspace’s definitions or to shipped blueprints, never to a file on the server.
Runs have a time limit, 5 seconds on the hosted service.
From an Application
The CLI is for building and publishing. Applications call the JSON API directly, or through the
reason_me_this Ruby gem, which reads numbers back as BigDecimal and dates as Date:
ReasonMeThis.configure do |config|
config.url = ENV['RMT_API_URL']
config.api_key = ENV['RMT_API_KEY']
end
ReasonMeThis.run('bill', facts).total # => 2.3
Every request and response is in the service’s OpenAPI spec.
Next Steps
- CLI Commands and Exit Codes - Every command, local and remote.
- Chaining with Imports and Runs - How imports join blueprints.
- Worked Examples - What the service runs before it publishes.