pogi
Reference

REST API

Endpoints that scripts call to control a running pogi.

All paths are on the main port, http://localhost:7644 by default. Bodies and answers are JSON unless noted. The cloud APIs themselves (S3, SQS, Pub/Sub and so on) are not listed here. Call those with the usual SDKs and CLIs.

pogi's own endpoints do not show up in Activity.

Method and pathPurpose
GET /_pogi/api/infoVersion, uptime, IAM (who may do what) mode and every service.
GET /_pogi/api/requestsRecent calls, with filters.
GET /_pogi/api/requests/{id}One call with headers and bodies.
GET /_pogi/api/resourcesResource tables of every service, or one.
GET /_pogi/api/resources/{service}/{table}/{id}The detail of one resource.
POST /_pogi/api/resetDelete state, for all services or some.
POST /moto-api/resetThe way moto (a Python AWS mock) and LocalStack reset.
GET /_pogi/api/snapshotsSaved snapshots.
POST /_pogi/api/snapshots/{name}Save all state under a name.
POST /_pogi/api/snapshots/{name}/loadReplace the state with a snapshot.
GET /_pogi/api/snapshots/{name}Get the snapshot file.
PUT /_pogi/api/snapshots/{name}Store a snapshot file under a name.
DELETE /_pogi/api/snapshots/{name}Remove a snapshot.
GET /_pogi/api/chaosActive fault-injection rules.
POST /_pogi/api/chaosAdd a rule.
DELETE /_pogi/api/chaos/{id}Remove one rule.
DELETE /_pogi/api/chaosClear every rule.
GET /_aws/sqs/messagesRead a queue without receiving.
GET, DELETE /_aws/sesEmails sent through SES.
GET, DELETE /_aws/sns/sms-messagesSMS sent through SNS.
GET, DELETE /_aws/sns/platform-endpoint-messagesPush messages sent through SNS.
GET /_aws/cognito/codesCodes Cognito "sent".
GET /_localstack/healthLocalStack's health endpoint.
GET /_localstack/infoLocalStack's info endpoint.
GET /_localstack/init/{stage}State of the init scripts. Leave out the stage for all four.
GET /_gcp/gke/kubeconfig/{project}/{location}/{cluster}Kubeconfig for a GKE cluster pogi runs.
/_pogi/mcppogi's MCP endpoint.

Same-origin rule

Writes to /_pogi/api/, /_localstack/, /moto-api/ and the console's form posts answer 403 when the request carries an Origin header that does not match the Host header. Tools such as curl and server-side code send no Origin, so they are not affected. A page in a browser on another origin is.

Status

Get status

GET /_pogi/api/info

Returns the status of pogi. pogi status and pogi wait call it.

curl localhost:7644/_pogi/api/info
Response
{
 "version": "0.1.0",
 "started": "2026-10-13T23:41:35.879922+05:30",
 "uptime": 15,
 "region": "us-east-1",
 "persist": false,
 "dataDir": "/home/me/.pogi",
 "iam": "off",
 "lambda": "auto",
 "ready": true,
 "services": [
  {"name": "s3", "cloud": "aws", "title": "S3", "resources": 1, "requests": 3},
  {"name": "sqs", "cloud": "aws", "title": "SQS", "resources": 0, "requests": 0}
 ]
}
  • uptime is in seconds.
  • ready is true once pogi serves requests. That is after the start init hooks and the seed data in pogi.yaml have run.
  • services has one entry for every enabled service. The example shows two.

Calls and resources

List requests

GET /_pogi/api/requests

Returns the recent calls, oldest first, without headers and bodies. pogi keeps the last 1000.

QueryTypeDefaultMeaning
limitnumber200The most calls to return. The newest ones are kept.
afternumber0Only calls with an id above this number.
servicestringanyOnly this service id (the name pogi services prints), such as s3.
qstringnoneOnly calls whose service, operation, path or error contains this text, ignoring case.
errorsany valueoffOnly calls with a status of 400 or above.
waitseconds0Wait for a call newer than after before answering, at most 60. Use it to follow the log.
curl "localhost:7644/_pogi/api/requests?errors=1&limit=1"
Response
[{"id":3,"time":"2026-10-13T23:41:51.597753+05:30","cloud":"aws","service":"s3","op":"GetObject","method":"GET","path":"/000000000000/jobs","status":404,"ms":0.038,"account":"000000000000","region":"us-east-1","requestId":"1f94db90…","principal":"arn:aws:iam::000000000000:root","error":"NoSuchBucket","trace":"1-8f78bfaf-8885d0da627d5eb7ca8d0cad"}]

The fields of an entry:

FieldMeaning
idA number that grows with each call.
time, msWhen the call arrived, and how long it took in milliseconds.
cloud, service, opThe cloud, service id and operation.
method, path, statusThe HTTP method, path and answer status.
account, region, requestId, accessKey, principalWho called, where and as whom. Left out when empty.
errorThe error code, when the call failed.
chaostrue when a chaos rule changed the call.
iamallow or deny: why, when IAM enforcement is on.
traceThe flow the call belongs to. See Flows and the Map.

Get one request

GET /_pogi/api/requests/{id}

Returns one call in full. It adds reqHeaders, reqBody and respBody. The Authorization header shows as [redacted].

curl localhost:7644/_pogi/api/requests/3
Response
{"id":3,"service":"s3","op":"GetObject","status":404,"error":"NoSuchBucket","reqHeaders":{"Accept":"*/*","User-Agent":"curl/8.7.1"},"respBody":"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Error><Code>NoSuchBucket</Code>…</Error>", …}
  • A call that has left the log answers 404 with {"error":"request not found (the log keeps the last 1000)"}.

List resources

GET /_pogi/api/resources

Returns the resource tables of every service. pogi ls calls it.

QueryTypeDefaultMeaning
servicestringallOnly this service id.
curl "localhost:7644/_pogi/api/resources?service=s3"
Response
{"s3":[{"name":"Buckets","columns":["Name","Region","Account","Objects","Size","Versioning","Created"],"rows":[["demo","us-east-1","000000000000","0","0 B","","2026-10-13 18:11:51"]]}]}

Get one resource

GET /_pogi/api/resources/{service}/{table}/{id}

Returns the detail of one resource.

curl localhost:7644/_pogi/api/resources/s3/Buckets/demo
Response
{"account":"000000000000","config":{},"created":"2026-10-13T18:11:51.580874Z","keys":0,"name":"demo","region":"us-east-1","uploads":0,"versioning":""}
  • If there is no such resource, the answer is 404 with {"error":"resource not found"}.

Reset and snapshots

Reset state

POST /_pogi/api/reset

Deletes state. pogi reset calls it. The seed data in pogi.yaml is created again afterward.

QueryTypeDefaultMeaning
servicestringallComma-separated service ids to reset.
curl -X POST "localhost:7644/_pogi/api/reset?service=s3,sqs"
Response
{"reset":["s3","sqs"]}

With no service, the answer is {"reset":null}.

Reset all state (moto)

POST /moto-api/reset

Resets every service, the way moto and LocalStack tools expect.

curl -X POST localhost:7644/moto-api/reset
Response
{"status":"ok"}

List snapshots

GET /_pogi/api/snapshots

Lists the saved snapshots. See Save and load snapshots.

curl localhost:7644/_pogi/api/snapshots
Response
[{"name":"demo","size":13691,"saved":"2026-10-13T23:42:04.620597368+05:30"}]

A snapshot name may use letters, digits, ., _ and -. The snapshot calls below answer 400 with {"error":"…"} for a bad name or a failed action.

Save a snapshot

POST /_pogi/api/snapshots/{name}

Saves all state under {name}.

curl -X POST localhost:7644/_pogi/api/snapshots/demo
Response
{"snapshot":"demo"}

Load a snapshot

POST /_pogi/api/snapshots/{name}/load

Replaces the current state with the snapshot {name}.

curl -X POST localhost:7644/_pogi/api/snapshots/demo/load
Response
{"snapshot":"demo"}

Download a snapshot

GET /_pogi/api/snapshots/{name}

Downloads the snapshot file, {name}.json.

curl -o demo.json localhost:7644/_pogi/api/snapshots/demo

Import a snapshot

PUT /_pogi/api/snapshots/{name}

Stores the request body, a snapshot file, under {name}.

curl -X PUT --data-binary @demo.json localhost:7644/_pogi/api/snapshots/copy
Response
{"snapshot":"copy"}

Delete a snapshot

DELETE /_pogi/api/snapshots/{name}

Deletes the snapshot.

curl -X DELETE localhost:7644/_pogi/api/snapshots/copy
Response
{"snapshot":"copy"}

Chaos

List chaos rules

GET /_pogi/api/chaos

Lists the rules. See Inject chaos.

curl localhost:7644/_pogi/api/chaos
Response
[{"id":"f2c47b28","service":"dynamodb","probability":0.25,"latencyMs":200,"hits":0}]

Add a chaos rule

POST /_pogi/api/chaos

Adds a rule from a JSON body and returns it with its id.

FieldTypeDefaultMeaning
servicestringanyService to match, as a pattern.
opstringanyOperation to match, as a pattern, such as Put*.
cloud, region, principal, pathstringanyMore patterns to match.
probabilitynumber0Chance that a matching call is affected, from 0 to 1. 0 means always.
latencyMsnumbernoneDelay to add, in milliseconds.
statusnumbernoneHTTP status to answer with.
codestringnoneError code to return.
messagestringnoneError message to return.

The answer also has id and hits, how often the rule has fired.

curl -X POST -H "content-type: application/json" \
  -d '{"service":"dynamodb","latencyMs":200,"probability":0.25}' \
  localhost:7644/_pogi/api/chaos
Response
{"id":"f2c47b28","service":"dynamodb","probability":0.25,"latencyMs":200,"hits":0}
  • A body that is not valid JSON answers 400 with {"error":"…"}.

Remove a chaos rule

DELETE /_pogi/api/chaos/{id}

Removes one rule.

curl -X DELETE localhost:7644/_pogi/api/chaos/f2c47b28

The answer is 204 with no body. If there is no such rule, it is 404 with {"error":"rule not found"}.

Remove all chaos rules

DELETE /_pogi/api/chaos

Removes every rule. The answer is 204 with no body.

curl -X DELETE localhost:7644/_pogi/api/chaos

Outboxes

These endpoints show what pogi captured instead of sending: queue messages, emails, texts, push messages and Cognito codes.

Peek at SQS messages

GET /_aws/sqs/messages

Reads a queue's messages without receiving them. See Migrate from LocalStack.

QueryTypeDefaultMeaning
QueueUrlstringnoneThe queue URL.
RegionstringanyThe queue's region. pogi finds the queue in any region when it is not given.

You can also put the queue in the path: GET /_aws/sqs/messages/{region}/{account}/{queue}.

curl localhost:7644/_aws/sqs/messages/us-east-1/000000000000/jobs
Response
{"messages":[{"MessageId":"12b3bfae-4999-4fd9-aaf6-786d4acdc7ff","Body":"hello","SentTimestamp":"2026-10-13T18:11:57.486148Z","ApproximateReceiveCount":0,"State":"visible"}]}
  • An unknown queue answers 400 with {"error":"QueueDoesNotExist: The specified queue does not exist."}.

List or clear SES emails

GET /_aws/ses and DELETE /_aws/ses

Lists, or clears, the emails sent through SES.

QueryTypeDefaultMeaning
idstringallOnly this message id. On DELETE, it removes only this message.
emailstringallOnly messages from this sender. Lists only.
curl localhost:7644/_aws/ses
Response
{"messages":[{"Id":"280a2f0e7aae7dab-39f9247e-fa79-4078-8861-977ca26fd24f-000000","Region":"us-east-1","Account":"000000000000","Source":"a@example.com","Destination":{"ToAddresses":["b@example.com"]},"Subject":"hi","Body":{"text_part":"hello there","html_part":""},"Timestamp":"2026-10-13T18:14:04.490798Z"}]}

DELETE answers 204. Without id, it removes every message.

List or clear SMS messages

GET /_aws/sns/sms-messages and DELETE /_aws/sns/sms-messages

Lists, or clears, the SMS messages sent through SNS, grouped by phone number.

QueryTypeDefaultMeaning
phoneNumberstringallOnly this number. Write + as %2B.
accountIdstringallOnly this account.
regionstringallOnly this region.
curl "localhost:7644/_aws/sns/sms-messages?phoneNumber=%2B15555550123"
Response
{"sms_messages":{"+15555550123":[{"Timestamp":"2026-10-13T18:14:04.69832Z","MessageId":"95dd1863-35ab-4dbb-a2ed-a70009bd536d","AccountId":"000000000000","Region":"us-east-1","Protocol":"sms","Destination":"+15555550123","Message":"code 1"}]}}

DELETE removes the messages that match the filters and answers 204.

List or clear push messages

GET /_aws/sns/platform-endpoint-messages and DELETE /_aws/sns/platform-endpoint-messages

The same as SMS messages, for push messages. Filter with endpointArn instead of phoneNumber, and with accountId and region.

curl localhost:7644/_aws/sns/platform-endpoint-messages
Response
{"platform_endpoint_messages":{}}

List Cognito codes

GET /_aws/cognito/codes

Lists the confirmation and verification codes Cognito "sent".

QueryTypeDefaultMeaning
poolstringallOnly this user pool id.
usernamestringallOnly this user name or destination address.
curl localhost:7644/_aws/cognito/codes
Response
[{"pool":"us-east-1_ak5Yfk9FS","username":"u@example.com","destination":"u@example.com","code":"961860","type":"SignUp","timestamp":"2026-10-13T23:44:05.547334+05:30"}]

LocalStack compatibility

Get LocalStack health

GET /_localstack/health

LocalStack's health endpoint. It lists every enabled service as running. The keys of services are pogi's service ids (pogi services lists them).

curl localhost:7644/_localstack/health
Response
{"edition":"community","services":{"accessanalyzer":"running","account":"running","acm":"running", …},"version":"pogi-0.1.0"}

Get LocalStack info

GET /_localstack/info

LocalStack's info endpoint.

curl localhost:7644/_localstack/info
Response
{"edition":"community","is_docker":false,"is_license_activated":false,"machine_id":"pogi","server_time_utc":"2026-10-13T18:11:51Z","session_id":"pogi","system":"darwin","uptime":15,"version":"pogi-0.1.0"}

Get init hook status

GET /_localstack/init and GET /_localstack/init/{stage}

Returns the state of the init hooks. {stage} is boot, start, ready or shutdown. Without a stage, the answer covers all four.

curl localhost:7644/_localstack/init/ready
Response
{"completed":true,"scripts":[{"stage":"READY","name":"10-seed.sh","state":"SUCCESSFUL","output":"make_bucket: from-init\n"}]}

With no hooks, scripts is null for a stage, and [] for the whole list:

Response
{"completed":{"BOOT":true,"READY":true,"SHUTDOWN":false,"START":true},"scripts":[]}

Other

Get a GKE kubeconfig

GET /_gcp/gke/kubeconfig/{project}/{location}/{cluster}

Returns a kubeconfig for a Google Kubernetes Engine cluster that pogi runs. pogi kubeconfig gke calls it.

curl localhost:7644/_gcp/gke/kubeconfig/pogi/us-central1/dev
  • With no such cluster, the answer is 404 with no cluster projects/pogi/locations/us-central1/clusters/dev.

MCP server

/_pogi/mcp

The MCP server, over Streamable HTTP.

The rest of /_pogi/ is the web console. Its other paths are pages and form posts for the console and may change between releases. Use the endpoints above from scripts.

See also

  • CLI: the commands that call these endpoints.
  • Console: the pages and form posts behind /_pogi/.

On this page