Log inTalk to us

Resume a paused batch

post/v1/migrations/{migration_id}/batches/{batch_id}/resume
Requires an API key

After a manual pause, the canary wave, too many failures, a rollback or a missing runner. Refused unless a runner was seen in the last 60 seconds. Its next moves are asked in the resumer's name. Needs migration:execute. Repeating it on a batch already there changes nothing. Audited in the same transaction. Errors: 404 migration_batch_not_found, 404 migration_not_found, 409 migration_batch_state, 409 migration_closed, 409 migration_runner_unhealthy, 503 migration_audit_unavailable. See Errors and statuses.

Path parameters

  • batch_idstringRequired
    Pattern ^bat_[0-9a-f]{32}$
  • migration_idstringRequired
    Pattern ^mig_[0-9a-f]{32}$

Returns · 200

  • idstringRequired
    bat_...
  • migration_idstringRequired
  • namestringRequired
  • statusenumRequired
    draft, submitted (waiting for the client's approval), approved, running, paused, completed, cancelled (moved chargers stay on Ivora) or rolled_back (a rollback of the batch was asked).
    One of draft, submitted, approved, running, paused, completed, cancelled, rolled_back
  • pacingPacingRequired
    Child attributes
    • wave_sizeintegerRequired
    • interval_secondsintegerRequired
    • canaryintegerRequired
    • max_failure_rationumberRequired
    • idle_timeout_minutesintegerRequired
    • move_timeout_minutesintegerRequired
  • countsobjectRequired
    Chargers per step, and total (of the caller's sites when narrowed).
  • waveintegerRequired
    Waves started.
  • wave_openbooleanRequired
    A wave's moves are out and not all answered.
  • next_wave_atstring | nullRequired
    When the next wave may start (running, between waves).
  • paused_reasonenum | nullRequired
    Why a paused batch paused: manual, canary (after its first wave), failure_ratio, rollback_requested (a rollback anywhere in the migration), runner_unhealthy or migration_paused (the migration was paused).
    One of manual, canary, failure_ratio, rollback_requested, runner_unhealthy, migration_paused
  • paused_atstring | nullRequired
  • job_idstringRequired
    The job of its moves (GET .../jobs/{job_id}).
  • created_bystringRequired
  • created_atstringRequired
  • updated_atstringRequired
  • submitted_bystring | nullRequired
  • submitted_atstring | nullRequired
  • approvalobject | nullRequired
    The client's approval; null until approved, and again after an edit.
    Child attributes
    • bystringRequired
    • roleenumRequired
      One of client, support, partner, observer
    • team_idstring | nullRequired
    • atstringRequired
    • chargersintegerRequired
      Chargers in the batch when it was approved.
    • digeststringRequired
      SHA-256 of the approved charger set and pacing; any edit revokes the approval.
  • started_bystring | nullRequired
    Who started it, or resumed it last: its moves are asked in their name.
  • started_atstring | nullRequired
  • finished_atstring | nullRequired
  • duration_snumber | nullRequired
    Seconds from its start to its end (or now while it runs).
  • rollbacksarray of BatchRollbackRequired
    Rollback jobs of its chargers, with their timings.
    Child attributes
    • job_idstringRequired
      The rollback job (GET .../jobs/{job_id}).
    • requested_atstringRequired
    • requested_bystringRequired
    • reasonstringRequired
    • chargersintegerRequired
      Chargers it rolls back (skipped ones left out).
    • appliedintegerRequired
      Chargers switched back by the proxy.
    • statusenumRequired
      One of running, succeeded, failed
    • last_applied_atstring | nullRequired
      When the proxy switched the last of them back.
    • switch_snumber | nullRequired
      Seconds from the request to the last switch back.
  • chargersarray of BatchCharger | nullRequired
    Each charger's step; null in a list.
    Child attributes
    • station_idintegerRequired
    • charger_keystringRequired
    • location_idinteger | nullRequired
    • stepenumRequired
      pending: waiting for its wave (detail busy: refused while charging, retried at retry_at). moving: its move request is out. moved: on Ivora. blocked: not moved (detail not_idle, not_proxied, shadow, rollback_pending). failed: the proxy failed or refused it, or did not answer in time (detail refused_parity, failed, expired). superseded: a rollback took over. skipped: the batch was cancelled or rolled back first, or the charger left the migration (detail).
      One of pending, moving, moved, blocked, failed, superseded, skipped
    • detailstring | nullRequired
    • waveinteger | nullRequired
      The wave of its latest move request.
    • attemptsintegerRequired
      Move requests sent for it (a busy charger is retried).
    • request_idstring | nullRequired
      Its latest move request (rr_...).
    • requested_atstring | nullRequired
    • retry_atstring | nullRequired
      A busy charger's next attempt at the earliest.
    • settled_atstring | nullRequired
    • move_snumber | nullRequired
      Seconds from its move request to the proxy's report that it moved.
POST /v1/migrations/{migration_id}/batches/{batch_id}/resume
curl --fail-with-body -X POST "https://api.ivoracharge.com/v1/migrations/mig_0123456789abcdef0123456789abcdef/batches/bat_0123456789abcdef0123456789abcdef/resume" \
  -H "Authorization: Bearer $IVORA_API_KEY"
Response · 200JSON
{
  "id": "id_0123456789abcdef",
  "migration_id": "migration_0123456789abcdef",
  "name": "bay-01",
  "status": "draft",
  "pacing": {
    "wave_size": 1,
    "interval_seconds": 1,
    "canary": 1,
    "max_failure_ratio": 1.5,
    "idle_timeout_minutes": 1,
    "move_timeout_minutes": 1
  },
  "counts": {},
  "wave": 1,
  "wave_open": false,
  "next_wave_at": "2026-09-30T17:00:00Z",
  "paused_reason": "manual",
  "paused_at": "2026-09-30T17:00:00Z",
  "job_id": "job_0123456789abcdef",
  "created_by": "string",
  "created_at": "2026-09-30T17:00:00Z",
  "updated_at": "2026-09-30T17:00:00Z",
  "submitted_by": "string",
  "submitted_at": "2026-09-30T17:00:00Z",
  "approval": {
    "by": "string",
    "role": "client",
    "team_id": "team_0123456789abcdef",
    "at": "string",
    "chargers": 1,
    "digest": "string"
  },
  "started_by": "string",
  "started_at": "2026-09-30T17:00:00Z",
  "finished_at": "2026-09-30T17:00:00Z",
  "duration_s": 1.5,
  "rollbacks": [
    {
      "job_id": "job_0123456789abcdef",
      "requested_at": "2026-09-30T17:00:00Z",
      "requested_by": "string",
      "reason": "string",
      "chargers": 1,
      "applied": 1,
      "status": "running",
      "last_applied_at": "2026-09-30T17:00:00Z",
      "switch_s": 1.5
    }
  ],
  "chargers": [
    {
      "station_id": 1,
      "charger_key": "string",
      "location_id": 7,
      "step": "pending",
      "detail": "string",
      "wave": 1,
      "attempts": 1,
      "request_id": "request_0123456789abcdef",
      "requested_at": "2026-09-30T17:00:00Z",
      "retry_at": "2026-09-30T17:00:00Z",
      "settled_at": "2026-09-30T17:00:00Z",
      "move_s": 1.5
    }
  ]
}
Requires an approved production API keyProduction access starts with a request, a short meeting with Ivora and a card on file, after which Ivora staff grant your account access. How to request access
Try itproduction · api.ivoracharge.com

Paste a production api key (iv_live_…). Create keys in Developer tools. The key stays in this page's memory, is sent only to https://api.ivoracharge.com and clears when you reload. Test keys are refused.

POST is a write: you confirm the method, path and project before it is sent, with a generated Idempotency-Key.