मुख्य सामग्री पर जाएँ

Jobs

Some operations take longer than a single request should wait - bulk imports, process publishing and status changes. These return a job id you poll until the work finishes.

Anything that touches the chain - publishing a process, changing its status, relaying a vote - and bulk member imports run asynchronously. The write returns a jobId, and you poll one endpoint to learn the outcome. This is the async spine of the API.

Polling a job

The generic job endpoint is public - the job id is the capability. Poll it until status is completed or failed, then read the result. Everyone gets the status and counters; per-row import error detail (which can reference member data) is added only for a logged-in manager/admin (a dashboard session) - scoped API keys are treated as anonymous on this endpoint.

GET/jobs/{jobId}
curl -s "$B/jobs/$JOBID"     # public: status + counters (per-row errors only for a manager session)
{ "jobId": "a1b2c3...",
  "type": "publish_voting_process",   // org_members | publish_voting_process |
                                      //   set_process_status | relay_vote
  "status": "completed",              // pending | completed | failed
  "result": { "status": "READY",      // on status change: the new status
              "voteID": "" },         // on relay_vote: the vote nullifier
  "errors": [] }                      // per-row import failures; omitempty (absent), manager session only
Field Type Description
jobId string Identifier returned when the work was enqueued.
type string What kind of work the job performs.
status string pending, completed or failed.
result object On success, details such as an address or vote id.
errors string[] Per-row import failures (line N: prefixed), returned only to a logged-in manager/admin (dashboard session); scoped API keys and anonymous callers get status and counters only. omitempty, so absent when empty.

Rules of thumb:

  • The call always returns 200, even for failures - branch on the status field.
  • completed: read result. failed: fail fast (don't keep polling); read errors for the reason (per-row import detail needs a manager/admin session). Anything else: keep polling (every ~2s is plenty).
poll to completion
// Polls until the job is done; throws JobFailedError on failure.
const job = await client.jobs.waitFor(jobId)
JsonElement job;
do { await Task.Delay(2000); job = await Get($"/jobs/{jobId}"); }
while (job.GetProperty("status").GetString() == "pending");
if (job.GetProperty("status").GetString() == "failed")
    throw new Exception(job.GetProperty("errors").ToString());
while True:
    job = get(f"/jobs/{jobId}").json()
    if job["status"] == "completed": break
    if job["status"] == "failed": raise RuntimeError(job["errors"])
    time.sleep(2)

Job types

  • org_members - bulk member import.
  • publish_voting_process - publishing a process (its census and one election per question, in one batch).
  • set_process_status - changing a question's status.
  • relay_vote - relaying a vote to the protocol.

The members-job

A bulk member add is an org_members job - poll the same generic GET /jobs/{jobId}. Its result carries the import counters (added, total, progress); top-level errors carries any per-row failures:

curl -s "${auth[@]}" "$B/jobs/$JOBID"
{ "type": "org_members", "status": "pending",
  "result": { "added": 120, "total": 200, "progress": 60 } }   // errors omitempty: absent when empty

When present, each entry in errors is prefixed with line N: - the 1-based position of the offending member in the list you submitted - so you can map a failure back to its input row. Per-row errors detail is returned only to a logged-in manager/admin (a dashboard session); anonymous and API-key polls get the counters only. Because errors is omitempty it is absent (never []) when there is nothing to report.

Wait for result.progress: 100 before publishing a process whose census uses the members. See Members and groups.

Listing jobs

You can list an organization's jobs with pagination and an optional type filter to monitor recent imports and batch operations.

GET/jobs?orgAddress={address}

Listing needs a dashboard session

GET /jobs currently requires a logged-in manager/admin; scoped API keys are rejected (403). Poll a known job by id (GET /jobs/{jobId}) if you only have an API key.

Jobs expire

Member import jobs are cleared shortly after they complete. Read the final state promptly rather than relying on the job being available indefinitely.