Status API
Status Endpoint
JSON endpoint for real-time monitoring of sync progress. Use it for scripting, dashboards, and automation.
Enabling the Endpoint
Pass --status-addr to expose the /status and /metrics HTTP endpoints.
godwit sync --source s3://src --dest s3://dst --status-addr :8080
curl -s localhost:8080/status | jq .Example Response
{
"run_id": "abc123",
"status": "running",
"source": "s3://my-source",
"destination": "s3://my-dest",
"started_at": "2026-02-25T10:00:00Z",
"finished_at": null,
"eta_seconds": 1847.3,
"objects": {
"total": 1250000,
"done": 980000,
"failed": 45,
"skipped": 8200,
"excluded": 3100,
"pending": 245000,
"running": 13655
},
"bytes": {
"total": 10995116277760,
"done": 8620171161762,
"failed": 2097152000,
"skipped": 52428800000,
"excluded": 10737418240,
"pending": 2240962269022,
"running": 68719476736
},
"version_history": {
"complete": 850000,
"partial": 320000,
"fully_skipped": 80000
},
"object_lock": {
"governance": 480000,
"compliance": 320000,
"legal_hold": 75000,
"none": 375000
},
"storage_classes": [
{ "name": "STANDARD", "count": 1050000, "bytes": 9200000000000, "percent": 84.0 },
{ "name": "INTELLIGENT_TIERING", "count": 125000, "bytes": 1200000000000, "percent": 10.0 },
{ "name": "GLACIER", "count": 75000, "bytes": 595116277760, "percent": 6.0 }
],
"verify": {
"matched": 975800,
"mismatched": 3,
"errors": 12,
"bytes": 8570000000000
},
"errors": ["upload failed on path/to/file.bin: connection reset"]
}Field Reference
Top Level
| Field | Type | Description |
|---|---|---|
| run_id | string | Unique identifier for this run |
| status | string | Run lifecycle state (running, planned, completed, failed) |
| source | string | Source URI (e.g. s3://bucket) |
| destination | string | Destination URI |
Object Counts
| Field | Type | Description |
|---|---|---|
| objects.total | int64 | Total objects discovered during planning |
| objects.done | int64 | Objects successfully transferred |
| objects.failed | int64 | Objects that failed to transfer |
| objects.skipped | int64 | Objects skipped (Glacier, unsupported key) |
| objects.excluded | int64 | Objects excluded by policy |
| objects.pending | int64 | Objects queued but not yet started |
| objects.running | int64 | Objects currently being transferred |
Byte Counts
| Field | Type | Description |
|---|---|---|
| bytes.total | int64 | Total bytes of all planned objects |
| bytes.done | int64 | Bytes successfully written |
| bytes.failed | int64 | Bytes in failed objects |
| bytes.skipped | int64 | Bytes in skipped objects |
| bytes.excluded | int64 | Bytes in excluded objects |
| bytes.pending | int64 | Bytes in pending objects |
| bytes.running | int64 | Bytes in objects currently transferring |
Timing & ETA
| Field | Type | Description |
|---|---|---|
| started_at | RFC 3339 | When the run started |
| finished_at | RFC 3339 | null | When the run finished (null while running) |
| eta_seconds | float64 | Estimated seconds to completion |
Version History
| Field | Type | Description |
|---|---|---|
| version_history.complete | int64 | Keys where all versions were successfully transferred |
| version_history.partial | int64 | Keys with mixed glacier-skipped and copied versions |
| version_history.fully_skipped | int64 | Keys where all versions were glacier-skipped |
Object Lock
| Field | Type | Description |
|---|---|---|
| object_lock.governance | int64 | Versions with GOVERNANCE retention mode |
| object_lock.compliance | int64 | Versions with COMPLIANCE retention mode |
| object_lock.legal_hold | int64 | Versions with legal hold enabled |
| object_lock.none | int64 | Versions with no Object Lock settings |
Verification
| Field | Type | Description |
|---|---|---|
| verify.matched | int64 | Objects whose computed MD5 matched the sidecar checksum |
| verify.mismatched | int64 | Objects whose computed MD5 did not match the expected checksum |
| verify.errors | int64 | Objects that could not be verified (e.g. missing sidecar, read error) |
| verify.bytes | int64 | Total bytes verified so far |
Storage Classes
| Field | Type | Description |
|---|---|---|
| storage_classes[].name | string | S3 storage class name (STANDARD, GLACIER, etc.) |
| storage_classes[].count | int64 | Number of objects in this class |
| storage_classes[].bytes | int64 | Total bytes in this class |
| storage_classes[].percent | float64 | Percentage of total objects |
Run Status Values
| Value | Meaning |
|---|---|
| running | Sync is in progress |
| planned | Plan-only mode completed |
| completed | All objects transferred successfully |
| failed | One or more objects failed |
Usage Examples
Poll Until Complete
while true; do
STATUS=$(curl -s localhost:8080/status | jq -r .status)
if [ "$STATUS" = "completed" ] || [ "$STATUS" = "failed" ]; then
echo "Run finished with status: $STATUS"
break
fi
sleep 5
doneProgress Snapshot
curl -s localhost:8080/status | jq '{
progress: (.objects.done / .objects.total * 100 | round),
eta: .eta_seconds,
failed: .objects.failed
}'