DEV Community

Cover image for Apidog CLI Tutorial: Test a REST API from the Command Line (Step by Step)
Hassann
Hassann

Posted on • Originally published at apidog.com

Apidog CLI Tutorial: Test a REST API from the Command Line (Step by Step)

Most API tests start in a GUI: you create requests, add assertions, and run them manually. That breaks down when the same tests need to run on every push, on a schedule, or inside CI where no one is clicking buttons. For that workflow, you need one command that can run your API tests, fail the build, and export reports.

Try Apidog today

Apidog CLI gives you that command. In this tutorial, you’ll test a real REST API from the terminal: install the CLI, import an API, configure an environment, create a test scenario, run assertions, feed test data, and generate reports. The examples use Apidog CLI 2.2.2 against a public API.

If you also want to design tests visually, you can download Apidog and run the same scenarios from the CLI later.

What you’ll build

You’ll test restful-api.dev, a free public REST API with CRUD operations over an /objects resource.

By the end, you’ll have:

  • An Apidog project created from an OpenAPI file
  • A three-step test scenario:
    • Create an object
    • Read it back
    • Delete it
  • Assertions at each step
  • A data-driven run using JSON test data
  • CLI, HTML, JSON, JUnit, and cloud reports

The same flow applies to your own API and is the foundation for running API tests in CI/CD.

Prerequisites

You need:

  • Node.js 16 or newer
  • An Apidog account
  • An Apidog API access token

If you’re comparing API test runners, Apidog CLI runs full test scenarios and manages API resources as code, which makes it different from Newman and the Postman CLI.

Step 1: Install Apidog CLI

Install the CLI globally from npm:

npm install -g apidog-cli@latest
Enter fullscreen mode Exit fullscreen mode

Verify the installation:

apidog --version
# 2.2.2
Enter fullscreen mode Exit fullscreen mode

Step 2: Log in with an API token

In the Apidog app, open:

Avatar menu → Account Settings → API Access Token
Enter fullscreen mode Exit fullscreen mode

Copy your token, then run:

apidog login --with-token <YOUR_TOKEN>
Enter fullscreen mode Exit fullscreen mode

The token is saved to:

~/.apidog/config.toml
Enter fullscreen mode Exit fullscreen mode

Check the authenticated account:

CLI commands return structured JSON with a success flag and agentHints, so you can script against the output or pipe it into tools like jq.

Step 3: Create a project

List your teams:

apidog team list
Enter fullscreen mode Exit fullscreen mode

Create a new project under the target team:

apidog project create --team 329562 --name "CLI Field Test"
Enter fullscreen mode Exit fullscreen mode

The command returns the new project ID.

Save it as a shell variable:

PID=1314366   # replace with your project id
apidog project get $PID
Enter fullscreen mode Exit fullscreen mode

Using variables keeps the remaining commands copy-paste friendly.

Step 4: Import the REST API from OpenAPI

You can create endpoints manually, but importing an OpenAPI file is faster and closer to how most teams start.

Create a file named objects-api.openapi.json:

{
  "openapi": "3.0.3",
  "info": { "title": "Objects API", "version": "1.0.0" },
  "servers": [{ "url": "https://api.restful-api.dev" }],
  "paths": {
    "/objects": {
      "get":  { "summary": "List objects" },
      "post": { "summary": "Create object" }
    },
    "/objects/{id}": {
      "get":    { "summary": "Get object by id" },
      "put":    { "summary": "Update object" },
      "delete": { "summary": "Delete object" }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Import it into your project:

apidog import --project $PID --format openapi --file ./objects-api.openapi.json
# "createCount": 5  (5 endpoints created, 0 errors)
Enter fullscreen mode Exit fullscreen mode

Apidog CLI can also import formats such as:

  • openapi
  • postman
  • har
  • insomnia
  • jmeter

List the imported endpoints:

apidog endpoint list --project $PID
# 37921721 get    /objects
# 37921722 post   /objects
# 37921723 get    /objects/{id}
# 37921724 put    /objects/{id}
# 37921725 delete /objects/{id}
Enter fullscreen mode Exit fullscreen mode

Step 5: Create an environment

An environment stores the base URL and reusable variables for test runs.

Create a production environment:

apidog environment create "Production" \
  --project $PID \
  --base-url "https://api.restful-api.dev"
Enter fullscreen mode Exit fullscreen mode

List environments and copy the ID:

apidog environment list --project $PID
# { "id": 6334917, "name": "Production", "baseUrls": { "default": "https://api.restful-api.dev" } }
Enter fullscreen mode Exit fullscreen mode

Save it:

ENV=6334917   # replace with your environment id
Enter fullscreen mode Exit fullscreen mode

You’ll pass this environment to apidog run later:

-e $ENV
Enter fullscreen mode Exit fullscreen mode

Step 6: Handle the automation write gate

Test scenarios and test data are automation resources. By default, writing them to the main branch from an external tool is blocked:

apidog test-scenario create \
  --project $PID \
  --name "x" \
  --description "" \
  --folder-id 0 \
  --priority 1

# "error": { "code": "403075", "message": "Automation caller branch required" }
Enter fullscreen mode Exit fullscreen mode

This is a guardrail. You have two options:

  1. Enable direct edit permission in the Apidog desktop app:
   Project Settings → Feature Settings → AI Feature Settings → External AI Edit Permissions
Enter fullscreen mode Exit fullscreen mode
  1. Work on an AI branch and merge later.

This tutorial uses the branch-based workflow.

Create an AI branch from main:

apidog branch create --project $PID --type ai \
  --name "ai/20260616-from-main-cli-field-test" \
  --from main
Enter fullscreen mode Exit fullscreen mode

Save the branch name:

BR="ai/20260616-from-main-cli-field-test"
Enter fullscreen mode Exit fullscreen mode

The expected naming pattern is:

ai/YYYYMMDD-from-<source>-<feature>
Enter fullscreen mode Exit fullscreen mode

Only automation resources are gated. Commands such as import, environment create, and endpoint edits are not gated.

Step 7: Create a test scenario

A scenario is an ordered flow of API requests with assertions.

Create the scenario shell:

apidog test-scenario create --project $PID --branch "$BR" \
  --name "Object CRUD lifecycle" \
  --description "Create, read, then delete an object and assert each step" \
  --folder-id 0 \
  --priority 1
Enter fullscreen mode Exit fullscreen mode

Save the returned scenario ID:

SID=1836498   # replace with your scenario id
Enter fullscreen mode Exit fullscreen mode

Step 8: Define scenario steps as JSON

You add steps with test-scenario update and a JSON file.

Before writing JSON payloads, inspect and validate the expected schema:

apidog cli-schema get test-scenario-update
apidog cli-schema validate test-scenario-update --file ./steps-crud.json
# "data file is valid"
Enter fullscreen mode Exit fullscreen mode

Each step contains:

  • The HTTP request
  • The request body, if needed
  • Post-processing scripts
  • Assertions
  • Variables passed to later steps

Here is the shape of the first step, which creates an object and stores its id:

{
  "type": "customHttp",
  "name": "Create object",
  "customHttpRequest": {
    "path": "https://api.restful-api.dev/objects",
    "method": "post",
    "requestBody": {
      "type": "json",
      "data": "{\"name\":\"Apidog CLI Field Test\",\"data\":{\"price\":42}}"
    },
    "postProcessors": [
      {
        "type": "customScript",
        "data": "pm.test('create returns 200', function () { pm.response.to.have.status(200); });\nvar body = pm.response.json();\npm.globals.set('objId', body.id);",
        "enable": true
      }
    ],
    "projectId": 1314366
  }
}
Enter fullscreen mode Exit fullscreen mode

The next steps can reuse the saved ID with:

{{objId}}
Enter fullscreen mode Exit fullscreen mode

For example:

https://api.restful-api.dev/objects/{{objId}}
Enter fullscreen mode Exit fullscreen mode

Apply the full three-step file:

apidog test-scenario update $SID \
  --project $PID \
  --branch "$BR" \
  --file ./steps-crud.json

# "success": true
Enter fullscreen mode Exit fullscreen mode

You can also build scenarios visually in Apidog and run them from the CLI. The JSON workflow is useful when you want test definitions version-controlled and reviewed like application code.

Step 9: Run the scenario from the terminal

Run the scenario with the CLI reporter:

apidog run -t $SID \
  --project $PID \
  --branch "$BR" \
  -e $ENV \
  -r cli
Enter fullscreen mode Exit fullscreen mode

Example output:

❏ Object CRUD lifecycle
↳ Create object        POST .../objects [200 OK]
  ✓ create returns 200   ✓ response has an id   ✓ name was echoed back
↳ Get the created object  GET .../objects/ff80...3de [200 OK]
  ✓ get returns 200   ✓ id matches the created object   ✓ price persisted in data
↳ Delete the object    DELETE .../objects/ff80...3de [200 OK]
  ✓ delete returns 200

  Http Requests  3 / 0 failed
  Assertions     7 / 0 failed
Enter fullscreen mode Exit fullscreen mode

The scenario made three requests, ran seven assertions, and passed the created id from the first step into the read and delete steps.

Step 10: Generate local reports

For CI or sharing, generate multiple report formats in one run:

apidog run -t $SID \
  --project $PID \
  --branch "$BR" \
  -e $ENV \
  -r cli,html,json,junit \
  --out-dir ./reports \
  --out-file "crud-report"
Enter fullscreen mode Exit fullscreen mode

Check the generated files:

ls ./reports
# crud-report.html  crud-report.json  crud-report.xml
Enter fullscreen mode Exit fullscreen mode

Use the reports as follows:

  • cli: terminal feedback
  • html: human-readable report for teammates
  • json: machine-readable run data
  • junit: CI-compatible pass/fail output

Step 11: Run the same test with multiple inputs

Real API tests usually need multiple cases. Data-driven runs execute a scenario once per row of data, similar to parameterized testing from CSV and JSON.

Create objects-data.json:

[
  { "name": "Pixel 8 Pro", "price": 999 },
  { "name": "iPhone 15", "price": 899 },
  { "name": "Galaxy S24", "price": 799 }
]
Enter fullscreen mode Exit fullscreen mode

Update your scenario so the request body reads values from each row:

{
  "name": "{{name}}",
  "data": {
    "price": "{{price}}"
  }
}
Enter fullscreen mode Exit fullscreen mode

Run the scenario with the data file:

apidog run -t $DID \
  --project $PID \
  --branch "$BR" \
  -e $ENV \
  -d ./objects-data.json \
  -r cli
Enter fullscreen mode Exit fullscreen mode

Example output:

Iteration 1/3 … ✓ row created (200) ✓ name matches the data row
Iteration 2/3 … ✓ row created (200) ✓ name matches the data row
Iteration 3/3 … ✓ row created (200) ✓ name matches the data row
  Iterations 3 / 0 failed   Assertions 6 / 0 failed
Enter fullscreen mode Exit fullscreen mode

Three rows produce three test iterations. You can swap the JSON file for CSV without changing the scenario structure.

Step 12: Upload a cloud report

Local reports are useful in CI. For a browser-accessible report your team can open, add --upload-report:

apidog run -t $SID \
  --project $PID \
  --branch "$BR" \
  -e $ENV \
  -r cli \
  --upload-report

# Apidog CLI runs data uploaded to the cloud successfully.
# https://app.apidog.com/link/project/1314366/api-test/test-report/2605398
Enter fullscreen mode Exit fullscreen mode

A cloud report is associated with the branch it ran on. Because this run used your AI branch, this command targets main and may not show it:

apidog test-report list --project $PID
Enter fullscreen mode Exit fullscreen mode

Fetch the report by ID instead:

apidog test-report get 2605398 --project $PID
Enter fullscreen mode Exit fullscreen mode

Download it as JSON:

apidog test-report download 2605398 \
  --project $PID \
  --format json \
  --output ./cloud-report.json
Enter fullscreen mode Exit fullscreen mode

Step 13: Export your API as a spec or docs

The CLI can also export project data.

Export OpenAPI:

apidog export \
  --project $PID \
  --format openapi \
  --oas-version 3.0 \
  --output ./openapi-export.json
Enter fullscreen mode Exit fullscreen mode

Export Markdown docs:

apidog export \
  --project $PID \
  --format markdown \
  --output ./api-docs.md
Enter fullscreen mode Exit fullscreen mode

Export HTML docs:

apidog export \
  --project $PID \
  --format html \
  --output ./api-docs.html
Enter fullscreen mode Exit fullscreen mode

This is useful when you want to commit a fresh API spec or publish static docs from a pipeline.

Step 14: Add the test run to CI/CD

Everything you ran locally can become a CI job.

The minimum pipeline flow is:

- run: npm install -g apidog-cli@latest
- run: apidog login --with-token $APIDOG_TOKEN
- run: apidog run -t $SID --project $PID -e $ENV -r junit --out-dir ./reports
Enter fullscreen mode Exit fullscreen mode

In CI:

  • Store APIDOG_TOKEN as a secret
  • Use the JUnit reporter for test result parsing
  • Archive ./reports as build artifacts
  • Let the CLI fail the job when tests fail

The CLI returns a non-zero exit code on failures, so most CI systems fail the build automatically.

For a complete workflow, see the guide to running Apidog CLI tests in GitHub Actions, or compare API test automation tools that fit a pipeline.

Wrapping up

You now have an end-to-end API test running from the terminal:

  1. Import an API definition
  2. Create an environment
  3. Build a scenario with assertions
  4. Run it with apidog run
  5. Feed it test data
  6. Export local and cloud reports
  7. Move the same command into CI

Point the same workflow at your own API, commit scenario files alongside your code, and your API tests can run anywhere a shell is available.

To get started visually, download Apidog. For quick one-off checks, keep these curl alternatives for REST API testing handy.

Top comments (0)