Graine AI
API referenceCampaigns

Get a campaign

Read one campaign.

Read one campaign.

A campaign belonging to another organisation answers 404, never 403 — /v2 never confirms that another tenant's ids exist.

Rate limit: 2000 requests per minute per organization, counted together with every endpoint that has no stricter limit of its own. Exceeding it returns 429 with Retry-After; the X-RateLimit-* response headers report your remaining allowance on every call.

GET
/v2/campaigns/{campaign_id}
/v2/campaigns/31ff3ea9-8bb5-433f-868f-286ac3c31328

The Authorization access token

Authorization

Authorization
Required
Bearer <token>

Your Graine API key. Create one in the dashboard under Developers, or via POST /v2/api-keys. Send it as Authorization: Bearer <key>.

In: header

Path Parameters

campaign_id
Required
Campaign Id

Campaign identifier.

Query Parameters

organization_idOrganization Id

Must match the organisation the API key belongs to.

Response Body

200

The campaign, its dialling policy and its stored counters.

batch_idBatch Id | null

The batch created from contacts on this request, if any were supplied. Null on every other read — a campaign can hold many batches; list them with GET /v2/campaigns/{campaign_id}/batches.

total_contactsTotal Contacts

Contacts across every batch.

Default: 0

skipped_countSkipped Count | null

Contacts of that list that were left out — each names an agent_language the agent doesn't have. Null when every contact was added, and on every other read.

skipped_rowsSkipped Rows | null

The contacts left out, each with its CSV line (the header is line 1) or its position in contacts, and why: the first 100. Null when every contact was added, and on every other read.

campaign_id
Required
Campaign Id

Campaign identifier.

organization_idOrganization Id | null

The organisation this campaign belongs to. Always your own.

name
Required
Name | null

Human label for the campaign.

agent_id
Required
Agent Id | null

Agent that places every call.

phone_numbersPhone Numbers

Caller IDs this campaign dials from.

phone_number_strategyPhone Number Strategy

round_robin | random | least_loaded.

Default: "round_robin"

phone_number_indexPhone Number Index

Round-robin cursor: the position the next call starts from.

Default: 0

timezoneTimezone

IANA timezone the working hours and the window are evaluated in.

Default: "UTC"

working_hours_enforcedWorking Hours Enforced

False dials around the clock, subject only to start_time/end_time.

Default: false

working_hoursWorking Hours

Per-day dialling windows, keyed by lowercase day name.

max_concurrent_callsMax Concurrent Calls | null

Ceiling on this campaign's SIMULTANEOUS calls. Omit for no campaign ceiling. It can only LOWER what the organisation's limit and the fair share across active campaigns already allow — raising it past the org limit has no effect.

retry_policy
Required
Retry Policy

What happens after a busy or a no-answer.

follow_up_policy
Required
Follow Up Policy

Callbacks after the first cycle ends.

transliteration
Required
Transliteration

Name-script rewriting inherited by every batch.

start_timeStart Time | null

ISO-8601 UTC. Nothing dials before this.

end_timeEnd Time | null

ISO-8601 UTC. Nothing dials after this; the campaign then expires.

default_call_variablesDefault Call Variables

Prompt variables applied to every call, overridable per contact.

default_call_contextDefault Call Context

Free-form context applied to every call.

status
Required
Status

created | active | paused | completed | cancelled | expired | archived. A campaign is born 'created' and becomes 'active' when its first batch dials. 'archived' is what DELETE leaves behind; 'cancelled' is what the cancel action does.

metadataMetadata

Whatever you stored on the campaign.

total_batchesTotal Batches

Batches created under this campaign.

Default: 0

active_batchesActive Batches

Batches not yet finished.

Default: 0

completed_contactsCompleted Contacts

Contacts that reached a completed call, counted ONCE regardless of how many attempts it took. Use this for progress, not completed_calls.

Default: 0

completed_callsCompleted Calls

Calls that completed, retries included.

Default: 0

failed_callsFailed Calls

Calls that failed.

Default: 0

busy_callsBusy Calls

Calls that hit a busy line.

Default: 0

no_answer_callsNo Answer Calls

Calls that rang out.

Default: 0

voicemail_callsVoicemail Calls

Calls answered by a voicemail box. A SUBSET of no_answer_calls, never a peer of it — do not add it to the others to form a total.

Default: 0

in_progress_callsIn Progress Calls

Calls live right now.

Default: 0

follow_up_callsFollow Up Calls

Follow-up calls placed.

Default: 0

follow_up_exhaustedFollow Up Exhausted

Contacts whose follow-up attempts ran out.

Default: 0

created_atCreated At | null

ISO-8601 UTC.

updated_atUpdated At | null

ISO-8601 UTC.

started_byStarted By | null

Who started its latest run: {type: member | api_key | system, id, at}. A person is their member id. Null on a campaign that has not started.

approved_byApproved By | null

The workspace Admin who approved that start, when the workspace requires approval: {type: member, id, at, request_id}. Null when it started without needing one.

400

1000 — malformed or contradictory input: an unknown status filter or timezone, a start_time or end_time without a timezone offset, an end_time at or before start_time or more than 365 days ahead, or an empty patch body. 1002 — a required parameter is missing.

error
Required
Error

Stable integer code from the /v2 error table. Branch on this.

message
Required
Message

One human-readable sentence. Wording may change; the code will not.

401

1100 — missing, unknown or inactive API key. 1101 — a browser session token was presented.

error
Required
Error

Stable integer code from the /v2 error table. Branch on this.

message
Required
Message

One human-readable sentence. Wording may change; the code will not.

403

1102 — the key is valid but lacks the scope this endpoint requires, or names another organisation. GET /v2/scopes reports which scopes the key holds.

error
Required
Error

Stable integer code from the /v2 error table. Branch on this.

message
Required
Message

One human-readable sentence. Wording may change; the code will not.

404

1200 — no such campaign, or no such agent, in this organisation. A campaign belonging to another organisation answers 404, never 403, so ids cannot be probed.

error
Required
Error

Stable integer code from the /v2 error table. Branch on this.

message
Required
Message

One human-readable sentence. Wording may change; the code will not.

422

1001 — the body or query failed validation — an unknown field, a value out of range, or a working-hours time that is not 24-hour HH:MM. The message names the first offending field.

error
Required
integer

Stable integer code from the error table. Branch on this, not on the message.

message
Required
string

One human-readable sentence. Wording may change; the code will not.

429

1300 — per-organisation rate limit exceeded. Carries Retry-After.

error
Required
Error

Stable integer code from the /v2 error table. Branch on this.

message
Required
Message

One human-readable sentence. Wording may change; the code will not.

503

1501 — a service this endpoint depends on is unreachable or returned a 5xx.

error
Required
Error

Stable integer code from the /v2 error table. Branch on this.

message
Required
Message

One human-readable sentence. Wording may change; the code will not.

504

1502 — a service this endpoint depends on did not respond in time.

error
Required
Error

Stable integer code from the /v2 error table. Branch on this.

message
Required
Message

One human-readable sentence. Wording may change; the code will not.

curl -X GET "https://api.graine.ai/v2/campaigns/31ff3ea9-8bb5-433f-868f-286ac3c31328?organization_id=string" \
  -H "Authorization: Bearer <token>"

The campaign, its dialling policy and its stored counters.

{
  "batch_id": "fa08ae9d-239f-4a99-8d76-d4dec51311b4",
  "total_contacts": 3000,
  "skipped_count": 2,
  "skipped_rows": [
    {
      "row": 7,
      "reason": "agent_language \"fr\" is not one of this agent's languages: en, hi, ta."
    }
  ],
  "campaign_id": "31ff3ea9-8bb5-433f-868f-286ac3c31328",
  "organization_id": "string",
  "name": "Slot-2-Uttar-Pradesh",
  "agent_id": "6c6f4cc3-f56c-479d-8422-7f76694daa29",
  "phone_numbers": [
    "+917971442184"
  ],
  "phone_number_strategy": "round_robin",
  "phone_number_index": 0,
  "timezone": "Asia/Kolkata",
  "working_hours_enforced": true,
  "working_hours": {
    "monday": {
      "start": "08:00",
      "end": "20:00",
      "enabled": true
    },
    "saturday": {
      "start": "10:00",
      "end": "16:00",
      "enabled": true
    },
    "sunday": {
      "start": "10:00",
      "end": "16:00",
      "enabled": false
    }
  },
  "max_concurrent_calls": 10,
  "retry_policy": {
    "max_retries": 5,
    "strategy": "fixed_delay",
    "cooldown_minutes": 45,
    "base_delay_minutes": 15,
    "max_delay_minutes": 240,
    "respect_working_hours": true
  },
  "follow_up_policy": {
    "enabled": false,
    "max_attempts": 2,
    "cooldown_minutes": 1440,
    "triggers": [
      "after_retries_exhausted"
    ],
    "next_working_day_only": true,
    "follow_up_agent_id": "6c6f4cc3-f56c-479d-8422-7f76694daa29",
    "follow_up_prompt": "You spoke to this person yesterday. Open by referring to that call.",
    "follow_up_extra_logic": {}
  },
  "transliteration": {
    "enabled": true,
    "fields": [
      "callee_name"
    ],
    "target_language_code": "hi-IN",
    "source_language_code": "en-IN",
    "keep_original": true
  },
  "start_time": "2026-08-27T05:30:00.000Z",
  "end_time": "2026-08-31T11:00:00.000Z",
  "default_call_variables": {
    "campaign_offer": "monsoon-renewal"
  },
  "default_call_context": {},
  "status": "paused",
  "metadata": {
    "region": "uttar-pradesh",
    "slot": "2"
  },
  "total_batches": 1,
  "active_batches": 1,
  "completed_contacts": 412,
  "completed_calls": 451,
  "failed_calls": 88,
  "busy_calls": 37,
  "no_answer_calls": 120,
  "voicemail_calls": 14,
  "in_progress_calls": 3,
  "follow_up_calls": 0,
  "follow_up_exhausted": 0,
  "created_at": "2026-08-26T10:48:18.239Z",
  "updated_at": "2026-08-26T10:51:46.003Z",
  "started_by": {
    "type": "member",
    "id": "member-live-0f1e2d3c",
    "at": "2026-08-26T10:51:46.003Z"
  },
  "approved_by": {
    "type": "member",
    "id": "member-live-9a8b7c6d",
    "at": "2026-08-26T10:52:10.411Z",
    "request_id": "apr_3f9c1d2e4b5a6978c0d1"
  }
}