Skip to content
Documentation

Cloud

Publish a curl-runner collection to curl-runner Cloud from CI, share it with a link, and pull a shared collection to your machine. Private preview.

Private preview

curl-runner Cloud is in private preview. Sign-ups open at launch. Until then the commands on this page talk to a server that only accepts people we have invited. You can also run the server yourself.

Cloud keeps a copy of your collection where your team and your customers can open it. Git stays the source of truth. Your CI publishes the folder on every push, and Cloud shows the latest version.

  • Publish a folder of YAML files from CI with curl-runner publish.
  • Share it with a link, or with named people.
  • Pull a shared collection onto your machine with curl-runner pull.

What leaves your machine

Publishing sends the YAML files in the folder, the cloud: name, description and inputs, and the git commit, ref and repository when your CI provides them. That is all.

Secret values never leave your machine. A secret input is declared by name only. Its value is set by whoever runs the collection, on their own machine. publish refuses to send a folder where a secret input has a literal value in a variables block (global, collection or top level).

Files over 1 MiB, and folders over 2,000 files or 25 MiB, are refused.

Declare the collection

Add a cloud: block to curl-runner.yaml in the collection folder:

curl-runner.yaml
cloud:
  collection: payments-api
  name: Payments API
  description: Smoke tests for the payments service.
  inputs:
    - name: BASE_URL
      description: Where the API runs.
      default: https://api.example.com
    - name: API_TOKEN
      description: A token for the staging API.
      secret: true
      required: true
KeyWhat it does
collectionThe collection's slug. Lowercase letters, digits and dashes, up to 63 characters. Required.
nameA display name, 1 to 100 characters.
descriptionUp to 500 characters.
inputsThe values a person fills in before running the collection.

Each input has these keys:

KeyWhat it does
nameLetters, digits and underscores, not starting with a digit. Required.
descriptionShown next to the input.
secretHides the value. Defaults to true for names that start with SECRET_, else false.
requiredThe collection can't run until it is set. Defaults to false.
lockedThe person running the collection can't change it. Defaults to false.
defaultA starting value. A secret input can't have one.

If a non-secret input has no default, the value of the variable with the same name in collection.variables or global.variables is used.

Publish from CI

Command
curl-runner publish
Output
payments-api: published v3 (1 added, 2 changed, 0 removed)

publish checks every file on your machine first and sends nothing if anything is wrong. An unchanged folder is not published again:

Output
payments-api: unchanged (v3)
Options
curl-runner publish [DIR...] [--collection <slug>] [--team <slug>] [--server <url>] [--dry-run]
OptionWhat it does
DIR...Folders to publish. Defaults to the current folder. Each folder is one collection.
--collectionOverrides cloud.collection. Works with one folder.
--teamThe team to publish to. Falls back to CURL_RUNNER_TEAM.
--serverThe API URL. Falls back to CURL_RUNNER_SERVER, then https://api.curl-runner.com.
--dry-runChecks the files and shows what would change. Sends nothing.

The token comes from CURL_RUNNER_TOKEN, or from the session that curl-runner login saved. A publish token (crt_...) belongs to one team, so you must give it a team. A signed-in account that is in one team needs no --team.

Publishing records the commit, ref and repository from GitHub Actions or GitLab CI, so each version links back to git.

Exit codes

CodeMeaning
0Published, or nothing to change.
1Invalid files, or a bad option or --server. Nothing was sent.
2Not signed in, or the token can't publish to that team.
3Your plan's limit was reached.
4The collection's source is the studio, not git. Switch its source to git, then publish again.
5The server could not be reached.

publish tries a request up to five times, waiting longer each time, before it exits with 5.

With more than one folder, a refusal from the server for one folder does not stop the others. Each failure is printed with its collection, and the exit code is the most severe one: 5, then 2, 4, 3, 1. An unreachable server stops the run at once.

A config file named .curl-runner.yaml is not published, so publish stops with exit 1 and asks you to rename it to curl-runner.yaml.

login, logout, publish and pull all exit 1 for a bad option, a missing value or a bad --server. Exit 2 is only for sign-in problems.

GitHub Action

The repo ships a composite action that installs the CLI and runs publish.

.github/workflows/publish.yml
name: Publish to curl-runner Cloud

on:
  push:
    branches: [main]

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - uses: alexvcasillas/curl-runner/actions/publish@main
        with:
          token: ${{ secrets.CURL_RUNNER_TOKEN }}
          team: acme
          path: collections/*
          version: 2.5.0
InputDefaultWhat it does
tokennoneThe publish token. Required. Keep it in a repository secret.
teamnoneThe team slug. Required.
path.Folders to publish, separated by spaces. Globs such as collections/* expand.
serverhttps://api.curl-runner.comThe API URL. Set it for a self-hosted server.
versionlatestThe @curl-runner/cli version to install. Pin the current release, as in the example.

Pin it

@main moves with every commit. For a workflow that holds a token, pin the action to a commit SHA, such as alexvcasillas/curl-runner/actions/publish@<full-commit-sha>, and pin version too.

Any other CI works the same way. Install the CLI, set CURL_RUNNER_TOKEN and CURL_RUNNER_TEAM, and run curl-runner publish.

Create a team

API only for now

Until the dashboard is out, you create a team with the API. Sign in first with curl-runner login.

An account that isn't in a team can't publish. Create one with a signed-in session. This reads the session curl-runner login saved:

Create a team
SESSION=$(jq -r '.servers["https://api.curl-runner.com"].session' ~/.config/curl-runner/credentials.json)
curl -X POST https://api.curl-runner.com/v1/teams \
  -H "Authorization: Bearer $SESSION" \
  -H "Content-Type: application/json" \
  -d '{"slug": "acme", "name": "Acme"}'

On a self-hosted server, SIGNUP decides who can do this. See Self-hosting.

Share a collection

API only for now

The dashboard is not out yet. Until it is, you share a collection with the API. These calls need a signed-in session as a team member, sent as Authorization: Bearer crs_.... curl-runner login saves one in ~/.config/curl-runner/credentials.json.

Each collection has a share link and an access mode: off, public or restricted. In restricted mode only the people on the access list can open the link. Restricted sharing needs the Team plan.

Restrict it
curl -X PATCH https://api.curl-runner.com/v1/teams/acme/collections/payments-api/share \
  -H "Authorization: Bearer $SESSION" \
  -H "Content-Type: application/json" \
  -d '{"access": "restricted"}'

Use "public" instead to let anyone with the link open it. The reply has the link:

Reply
{
  "access": "restricted",
  "link": "https://cloud.curl-runner.com/s/<token>",
  "expires_at": null,
  "entries": []
}

PATCH also takes expires_in_days (null removes the expiry) and reset_link: true, which replaces the link and stops the old one working.

Then add people to the access list. An entry is an email, or *@example.com for everyone on a domain. notify sends an invite email, and only to email entries that are new:

Invite someone
curl -X POST https://api.curl-runner.com/v1/teams/acme/collections/payments-api/share/entries \
  -H "Authorization: Bearer $SESSION" \
  -H "Content-Type: application/json" \
  -d '{"entry": "dev@example.com", "notify": true}'

GET on the same /share path shows the link and the list. DELETE on /share/entries/<entry> removes someone.

A link is a credential

Whoever holds a share link can use it. In public mode that means anyone. Don't paste it where you wouldn't paste a password. If a link leaks, reset it.

Publish tokens

A publish token belongs to one team and can only publish. Create one as a signed-in member:

curl -X POST https://api.curl-runner.com/v1/teams/acme/tokens \
  -H "Authorization: Bearer $SESSION" \
  -H "Content-Type: application/json" \
  -d '{"name": "github-actions"}'

The reply shows the token once. Copy it into your CI's secrets. Add expires_in_days to make it expire, and DELETE /v1/teams/acme/tokens/<id> to revoke it.

Pull a shared collection

If someone shared a collection with you, pull it:

Command
curl-runner pull https://cloud.curl-runner.com/s/<token> payments-api
Output
Pulled Payments API v3 into payments-api. Fill in payments-api/.env (see .env.example), then run: cd payments-api && curl-runner --all

The files are written into the folder. Pulled secret inputs are listed in .env.example without values. Copy it to .env and fill them in. Run the collection from inside the folder, so its .env and curl-runner.yaml are used and nested folders are included.

To get the latest version later, run pull in that folder:

curl-runner pull payments-api
Output
Updated Payments API to v4.

If you changed a pulled file, pull asks before replacing it. Without a terminal, it stops and tells you to pass --force.

curl-runner pull [LINK] [DIR] [--force]

A share link can also look like curl-runner://open?server=<api-url>&share=<token>. It names the server itself, so pull doesn't have to look it up. Use it for a self-hosted server.

A collection that isn't public asks you to sign in. Run curl-runner login --server <url> first, or let pull offer it in a terminal. A pull writes nothing until every file passes the same path checks publish uses, so a bad bundle can't write outside the folder. Exit codes: 0 ok, 1 a problem with the link, the data or an option, 2 sign-in, 5 the server can't be reached.

Next steps