Instance API Reference

Instances are running Chrome browser processes managed by PinchTab. Each instance is associated with a profile (browser user data directory) and has its own independent browser state.

Quick Start

List Running Instances

bash terminal
# CLIpinchtab instances# Curlcurl http://localhost:9867/instances | jq .# Response[  {    "id": "inst_0a89a5bb",    "profileId": "prof_278be873",    "profileName": "Pinchtab org",    "port": "9868",    "headless": true,    "status": "running",    "startTime": "2026-03-01T05:21:38.27432Z"  }]

Start an Instance

bash terminal
# CLI (all parameters optional)pinchtab instance start# CLI with profilepinchtab instance start --profileId 278be873adeb# CLI with mode and portpinchtab instance start --mode headed --port 9999# Curlcurl -X POST http://localhost:9867/instances/start \  -H "Content-Type: application/json" \  -d '{"profileId": "278be873adeb", "mode": "headed", "port": 9999}'# Response{  "id": "inst_ea2e747f",  "profileId": "prof_278be873",  "profileName": "Pinchtab org",  "port": "9868",  "headless": false,  "status": "starting"}

Get Instance Logs

bash terminal
# CLIpinchtab instance logs inst_ea2e747fpinchtab instance logs --id inst_ea2e747f# Curlcurl http://localhost:9867/instances/inst_ea2e747f/logs

Stop an Instance

bash terminal
# CLIpinchtab instance stop inst_ea2e747fpinchtab instance stop --id inst_ea2e747f# Curlcurl -X POST http://localhost:9867/instances/inst_ea2e747f/stop# Response{  "id": "inst_ea2e747f",  "status": "stopped"}

Complete API Reference

1. List Instances

Endpoint: GET /instances

CLI:

bash terminal
pinchtab instances

Curl:

bash terminal
curl http://localhost:9867/instances | jq .

Response: Array of Instance objects

[
  {
    "id": "inst_0a89a5bb",
    "profileId": "prof_278be873",
    "profileName": "Pinchtab org",
    "port": "9868",
    "headless": true,
    "status": "running",
    "startTime": "2026-03-01T05:21:38.27432Z"
  }
]

Instance Status Values:

  • starting — Instance process spawning, Chrome initializing
  • running — Instance healthy and ready to accept commands
  • error — Instance failed to start
  • stopping — Instance is shutting down

2. Start Instance

Endpoint: POST /instances/start

CLI:

bash terminal
# All parameters optional - uses defaultspinchtab instance start# With specific profilepinchtab instance start --profileId 278be873adeb# With mode and portpinchtab instance start --profileId abc123 --mode headed --port 9999# Combine flagspinchtab instance start --mode headed --port 9998

Curl:

bash terminal
# Minimal (all defaults)curl -X POST http://localhost:9867/instances/start \  -H "Content-Type: application/json" \  -d '{}'# With profile IDcurl -X POST http://localhost:9867/instances/start \  -H "Content-Type: application/json" \  -d '{    "profileId": "278be873adeb",    "mode": "headed",    "port": "9999"  }'

Request Body (all optional):

{
  "profileId": "278be873adeb",
  "mode": "headed",
  "port": "9999"
}

Parameters:

  • profileId (string, optional) — Profile ID or name. If omitted, creates temporary instance
  • mode (string, optional, default: “headless”) — “headed” or “headless”
  • port (string, optional) — Port number. If omitted, auto-allocated from available ports

Response: Instance object

{
  "id": "inst_ea2e747f",
  "profileId": "prof_278be873",
  "profileName": "Pinchtab org",
  "port": "9868",
  "headless": false,
  "status": "starting",
  "startTime": "2026-03-01T05:21:38.27432Z"
}

Defaults:

  • profileId — If omitted, auto-generates temporary profile name
  • mode — Defaults to “headless” if not specified
  • port — Auto-allocated if not specified (finds first available port)

3. Get Instance Logs

Endpoint: GET /instances/{id}/logs

CLI:

bash terminal
# Positional argumentpinchtab instance logs inst_ea2e747f# With --id flagpinchtab instance logs --id inst_ea2e747f

Curl:

bash terminal
curl http://localhost:9867/instances/inst_ea2e747f/logs

Response: Text (plain text log output)

2026-03-01 05:21:38 INFO starting instance process id=inst_ea2e747f profile=Pinchtab org port=9868
2026-03-01 05:21:40 INFO instance ready id=inst_ea2e747f

Notes:

  • Returns raw text output (not JSON)
  • Includes timestamps and log levels
  • Useful for debugging instance startup issues

4. Stop Instance

Endpoint: POST /instances/{id}/stop

CLI:

bash terminal
# Positional argumentpinchtab instance stop inst_ea2e747f# With --id flagpinchtab instance stop --id inst_ea2e747f

Curl:

bash terminal
curl -X POST http://localhost:9867/instances/inst_ea2e747f/stop

Response:

{
  "id": "inst_ea2e747f",
  "status": "stopped"
}

Notes:

  • Gracefully shuts down Chrome process
  • Returns immediately (shutdown happens in background)
  • Instance moved to stopped state
  • Profile is preserved (not deleted)

Complete Workflow Examples

Example 1: Simple Start and Stop

bash terminal
#!/bin/bash# Start headless instance (auto-allocated port, temporary profile)INST=$(curl -s -X POST http://localhost:9867/instances/start \  -H "Content-Type: application/json" \  -d '{"mode":"headless"}' | jq -r .id)echo "Started instance: $INST"# Wait a moment for instance to be readysleep 2# Get logsecho "Instance logs:"curl -s http://localhost:9867/instances/$INST/logs | head -5# Stop instancecurl -s -X POST http://localhost:9867/instances/$INST/stop | jq .echo "Stopped instance: $INST"

Example 2: Start with Specific Profile

bash terminal
#!/bin/bash# Get first available profile IDPROF=$(curl -s http://localhost:9867/profiles | jq -r '.[0].id')echo "Using profile: $PROF"# Start instance with that profile in headed modeINST=$(curl -s -X POST http://localhost:9867/instances/start \  -H "Content-Type: application/json" \  -d "{    \"profileId\": \"$PROF\",    \"mode\": \"headed\",    \"port\": \"9999\"  }" | jq -r .id)echo "Started instance: $INST on port 9999"# List running instancesecho -e "\nRunning instances:"curl -s http://localhost:9867/instances | jq '.[] | {id, port, mode: (if .headless then "headless" else "headed" end)}'# Stop when donecurl -s -X POST http://localhost:9867/instances/$INST/stop

Example 3: CLI-Based Workflow

bash terminal
#!/bin/bash# Start instanceecho "Starting instance..."INST=$(pinchtab instance start --mode headed --port 9998 | jq -r .id)echo "Instance: $INST"# Wait for readysleep 3# View logsecho -e "\nInstance logs:"pinchtab instance logs $INST | tail -5# List instancesecho -e "\nRunning instances:"pinchtab instances | jq '.[] | {id, port}'# Stopecho -e "\nStopping..."pinchtab instance stop $INST

Example 4: Multiple Instances

bash terminal
#!/bin/bashdeclare -a INSTANCES# Start 3 instances with different profilesPROFILES=$(curl -s http://localhost:9867/profiles | jq -r '.[0:3] | .[] | .id')i=0for prof in $PROFILES; do  PORT=$((9868 + i))  INST=$(curl -s -X POST http://localhost:9867/instances/start \    -H "Content-Type: application/json" \    -d "{\"profileId\":\"$prof\",\"port\":\"$PORT\"}" | jq -r .id)  INSTANCES+=($INST)  echo "Started: $INST on port $PORT"  i=$((i + 1))done# Wait and verifysleep 2echo -e "\nRunning instances:"curl -s http://localhost:9867/instances | jq length | xargs echo "Count:"# Stop allecho -e "\nStopping all instances..."for inst in "${INSTANCES[@]}"; do  curl -s -X POST http://localhost:9867/instances/$inst/stop > /dev/null  echo "Stopped: $inst"done

CLI Examples

Quick Start with CLI

bash terminal
# List instancespinchtab instances# Start headless instancepinchtab instance start# Start headed instance on specific portpinchtab instance start --mode headed --port 9999# Start with profilepinchtab instance start --profileId 278be873adeb# Get logs (both syntaxes work)pinchtab instance logs inst_0a89a5bbpinchtab instance logs --id inst_0a89a5bb# Stop instance (both syntaxes work)pinchtab instance stop inst_0a89a5bbpinchtab instance stop --id inst_0a89a5bb

Script Example

bash terminal
#!/bin/bash# Simple instance management scriptcase "$1" in  "start")    pinchtab instance start --mode $2 --port $3    ;;  "logs")    pinchtab instance logs $2    ;;  "stop")    pinchtab instance stop $2    ;;  "list")    pinchtab instances    ;;  *)    echo "Usage: $0 {start|logs|stop|list} [args]"    ;;esac

Integration Examples

With Bash

bash terminal
# Start instance and capture IDINST=$(curl -s -X POST http://localhost:9867/instances/start \  -d '{}' | jq -r .id)# Use instancePORT=$(curl -s http://localhost:9867/instances | jq -r ".[] | select(.id == \"$INST\") | .port")echo "Instance $INST running on port $PORT"# Cleanupcurl -s -X POST http://localhost:9867/instances/$INST/stop

With Python

import requests
import json

BASE = "http://localhost:9867"

# Start instance
resp = requests.post(f"{BASE}/instances/start", json={
    "profileId": "278be873adeb",
    "mode": "headed",
    "port": "9999"
})
inst = resp.json()
print(f"Started: {inst['id']} on port {inst['port']}")

# List instances
instances = requests.get(f"{BASE}/instances").json()
print(f"Total running: {len(instances)}")

# Get logs
logs = requests.get(f"{BASE}/instances/{inst['id']}/logs").text
print("Recent logs:", logs[:200])

# Stop instance
resp = requests.post(f"{BASE}/instances/{inst['id']}/stop")
print(f"Stopped: {resp.json()}")

With JavaScript/Node.js

const BASE = "http://localhost:9867";

async function manageInstances() {
  // Start instance
  const startResp = await fetch(`${BASE}/instances/start`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      profileId: "278be873adeb",
      mode: "headed",
      port: "9999"
    })
  });
  const inst = await startResp.json();
  console.log(`Started: ${inst.id} on port ${inst.port}`);

  // List instances
  const listResp = await fetch(`${BASE}/instances`);
  const instances = await listResp.json();
  console.log(`Total running: ${instances.length}`);

  // Get logs
  const logsResp = await fetch(`${BASE}/instances/${inst.id}/logs`);
  const logs = await logsResp.text();
  console.log("Recent logs:", logs.substring(0, 200));

  // Stop instance
  const stopResp = await fetch(`${BASE}/instances/${inst.id}/stop`, {
    method: "POST"
  });
  const stopped = await stopResp.json();
  console.log(`Stopped: ${stopped.id}`);
}

manageInstances().catch(console.error);

Error Handling

Profile Not Found (404)

bash terminal
curl -X POST http://localhost:9867/instances/start \  -d '{"profileId":"nonexistent"}'# Response (400 Bad Request){  "error": "profile \"nonexistent\" not found",  "statusCode": 404}

Port Already in Use (409)

bash terminal
curl -X POST http://localhost:9867/instances/start \  -d '{"port":"9867"}'# Response (409 Conflict){  "error": "port 9867 already in use",  "statusCode": 409}

Instance Not Found (404)

bash terminal
curl http://localhost:9867/instances/nonexistent/logs# Response (404 Not Found){  "error": "instance not found",  "statusCode": 404}

Invalid JSON (400)

bash terminal
curl -X POST http://localhost:9867/instances/start \  -d 'invalid json'# Response (400 Bad Request){  "error": "invalid JSON",  "statusCode": 400}

Best Practices

Port Management

bash terminal
# Let PinchTab auto-allocate ports (recommended)pinchtab instance start# Or manually specify if you need a specific portpinchtab instance start --port 9999

Profile Selection

bash terminal
# Start with specific profile to preserve statepinchtab instance start --profileId 278be873adeb# Or use temporary profile (good for isolated testing)pinchtab instance start

Cleanup

bash terminal
# Always stop instances when donepinchtab instance stop $INSTANCE_ID# Check for orphaned instancespinchtab instances | jq length

Monitoring

bash terminal
# Check instance statuspinchtab instances | jq '.[] | {id, port, status}'# View recent logspinchtab instance logs $INSTANCE_ID | tail -20

Instance Lifecycle

Architecture Diagram ASCII
START (POST /instances/start)  [status: "starting"]  Chrome initializing, health checks running  [status: "running"]  Ready to accept commands  STOP (POST /instances/{id}/stop)  [status: "stopping"]  Graceful shutdown  Instance removed from list, profile preserved

Status Codes

CodeMeaningExample
200Success (GET)List retrieved, logs retrieved
201CreatedInstance started successfully
400Bad requestInvalid JSON, missing required field
404Not foundInstance/profile not found
409ConflictPort already in use, launch error
500Server errorInternal error

Summary Table

OperationMethodEndpointCLI
ListGET/instancespinchtab instances
StartPOST/instances/startpinchtab instance start [opts]
LogsGET/instances/{id}/logspinchtab instance logs <id>
StopPOST/instances/{id}/stoppinchtab instance stop <id>

FAQ

Q: What’s the difference between headless and headed mode? A: Headless runs without a GUI window (good for servers), headed shows the browser window (good for debugging).

Q: Can I run multiple instances simultaneously? A: Yes, each gets its own port and Chrome process.

Q: What happens to my profile when I stop an instance? A: Profile is preserved. Stop just closes the browser. You can start the same instance again.

Q: How do I choose between temporary and named profiles? A: Use named profiles when you need to preserve state (logins, settings). Use temporary when testing.

Q: Can I change the port after starting? A: No, port is assigned on start. Stop and restart with a new port if needed.

Q: How do I know when an instance is ready? A: Status transitions from “starting” to “running” when healthy.


  • Profile API (docs/references/profile-api.md) — Manage browser profiles
  • Tab API (docs/references/tab-api.md — coming soon) — Control tabs within instances
  • CLI Design (docs/references/cli-design.md) — CLI command patterns