sked http

Make authenticated, curl-style HTTP requests to the Skedulo API or to a local connected function from the command line.

Overview

Make authenticated, curl-style HTTP requests to the Skedulo API, or to a connected function that runs locally, from the command line. Give it a path and it resolves against your current tenant’s API and attaches your saved access token automatically, without you needing to look up or paste a bearer token.

An absolute URL is also accepted. The command attaches the token only when the URL’s origin matches your tenant’s own API, or when its host is a loopback address (127.0.0.1, [::1] or localhost). That second case lets you call a function that runs under sked function dev. The command calls any other host without a token. It is a tool for testing Skedulo APIs and functions, not a general-purpose HTTP client.

Run sked http with no URL in a terminal to open the same interactive request builder Skedulo CLI Studio uses, instead of sending a one-off request.

Usage

$ sked http [<url or path>] [--method <value>] [--header <value>]... [--data <value>] [--alias <value>] [--output <value>] [--verbose] [--include] [--fail] [--no-tenant-token] [--json]

Examples

# A GraphQL query
$ sked http /graphql/graphql -H "Content-Type: application/json" \
  -d '{"query":"{ jobs(limit: 5) { edges { node { UID Name JobStatus } } } }"}'

# Geocode an address
$ sked http /geoservices/geocode -H "Content-Type: application/json" \
  -d '{"addresses":["47 Warner Street, Fortitude Valley QLD, Australia"]}'

# Send an SMS
$ sked http /notifications/sms -H "Content-Type: application/json" \
  -d '{"phoneNumber":"4001234567","countryCode":"AU","message":"Thanks for confirming your booking"}'

# Fetch the tenant's GraphQL schema straight to a file
$ sked http /graphql/schema -o schema.graphql

# Call a function that runs under `sked function dev <dir> -p 3000` (sends your saved token)
$ sked http http://127.0.0.1:3000/ping

# Call the same function without the token, for example to test how it handles a missing token
$ sked http http://127.0.0.1:3000/ping --no-tenant-token

# Open the interactive request builder
$ sked http

Flags

Flag Description Required
-X, --method= HTTP method (defaults to POST if --data is set, otherwise GET) No
-H, --header= Request header as "Key: Value" (repeatable) No
-d, --data= Request body No
-a, --alias= The alias of the Skedulo tenant to send the request to No
-o, --output= Write the response body to this file instead of stdout No
-v, --verbose Print the outgoing request line and headers before sending. The Authorization header is masked No
--include Include the response status and headers before the body. The Set-Cookie header is masked No
-f, --fail Exit non-zero if the response status is 400 or greater No
--no-tenant-token Do not attach your saved access token. An Authorization header that you pass with -H is still sent No

Global flags

Flag Description Required
--json Structured { status, statusText, headers, durationMs, body } output No

Token attachment

Which requests get the token

  • A relative path, such as /graphql/graphql, always resolves against your current tenant’s own API. The command sends the token with it.
  • An absolute URL gets the token only when its origin matches your tenant’s own API base path, or when its host is 127.0.0.1, [::1] or localhost. The port can be any port, and the scheme can be http or https. The command calls any other host without a token, including 0.0.0.0, 127.0.0.2 and LAN addresses.
  • --no-tenant-token never attaches the saved token, for any URL, including a relative path. It also skips the expiry check.
  • An Authorization header that you pass with -H is sent as you typed it, and the command does not attach the saved token, on a loopback URL and with --no-tenant-token. On your tenant’s own API, without --no-tenant-token, the saved token replaces your header. On any other host, your header passes through unchanged.
  • If the saved token has expired and the command would attach it, the command fails with the standard “log in again” error. For a loopback URL, the error also suggests --no-tenant-token.

Call a function under sked function dev

  1. Start the function on a known port. Without -p, the dev server picks a random port and prints it.

    $ sked function dev <dir> -p 3000
    
  2. Call the function from a second terminal.

    $ sked http http://127.0.0.1:3000/ping
    

The token that sked http sends decides which tenant the function acts on. The --alias flag on sked function dev only picks the API host, which depends on the environment and not on the tenant. Pass the same --alias to both commands, so that both use the same tenant.

The dev server listens on 127.0.0.1 by default. The command sends no token to a URL that uses a non-loopback --host address. Keep the default host when you want to call the function with a token.

Security considerations

  • Any process that listens on the loopback port receives the token. This includes a forwarded port (ssh -L, kubectl port-forward or a devcontainer), which can reach a remote service. Pass --no-tenant-token when you are not sure what listens on the port.
  • If you set NODE_USE_ENV_PROXY=1 to route requests through a proxy (Node.js 22.21.0 or later, or 24.0.0 or later), add the loopback hosts to NO_PROXY. Otherwise the proxy can read the token.
  • Before it sends an Authorization header to localhost, the command resolves localhost. If any resolved address is not 127.0.0.1 or ::1, for example because of an edited hosts file, the command sends nothing and fails. Use 127.0.0.1 instead of localhost to skip the lookup.
  • A redirect response (3xx) is shown as-is rather than followed, the same as curl’s own default. A redirect target is not origin-checked, so following it automatically could resend the request body to an unintended host.

Interactive request builder

The request builder and the HTTP Client in the Skedulo CLI Studio follow the same rules. Their headers list starts with a read-only Authorization: Bearer <tenant-token> line that stands for the saved token. The line ends with (sent), (expired, log in again) or (not sent, <reason>). It is dim when the screen sends no token. The reason is one of the following:

Reason Meaning
turned off You pressed a.
not logged in No tenant is logged in.
using your header You typed your own Authorization header for a local URL.
other host The URL is not your tenant’s API or a loopback address.

Two keys control the token and the tenant. They work when you are not typing in a field. The Body row is always a field, so select another row first.

Key Action
a Turn the saved token off or on. This does what --no-tenant-token does.
t Switch to another saved tenant. It does nothing when no other tenant is saved.

The token is on again each time you open the screen.

When you switch tenant, the next request uses the new tenant’s token. A URL that starts with the old tenant’s API moves to the new tenant’s API and keeps its path and query. Any other URL stays as you typed it. The switch clears the response. Your method, headers, body and a choice stay. In the request builder, --alias picks the tenant that the screen starts on.

On a local URL, the request carries the new tenant’s token, so the function acts on the new tenant. If the new tenant is in a different environment, restart sked function dev with --alias set to the new tenant. The dev server then calls that environment’s API.