NAV
shell Javascript Ruby Python

Getting started

Overview

Calls for ConvertKit API v4 are relative to the URL https://api.convertkit.com/

App developer access is in a closed beta and only developers who receive an invite can join the beta. Join the waitlist here.

If you were previously using ConvertKit API v3 and want to update to use our new functionality, please review our changelog for breaking changes between versions.

If you are unable to support OAuth authentication, continue using v3. API Key support is coming soon.

Planning your integration

Sweet! You’re building an integration with ConvertKit. We’re thrilled that you want to help expand our ever-growing platform! Our API offers a host of functionality to help our creators automate a bunch of tasks to help make their lives as easy as possible, especially by helping link their tech marketing stack together in perfect harmony.

As long as the authenticated account’s plan is eligible for use with the API and integrations, you will be able to create and send broadcasts to your subscribers, manage your email list through tags and custom fields, import in purchase data from your favourite e-commerce platforms and much, much more.

If you are a third party developer, once your app is complete, you will be able to publish it to the thousands of creators using our platform today.

For an overview of apps at ConvertKit, please check out our help centre articles that guide you through the creation of your app, its API access and plugin setup.

Authentication/Authorization

OAuth

We use the Authorization Code Grant with refresh tokens

You can set up your OAuth API Access in your developer settings. If you don't see an option to configure apps, please reach out to us.

When configuring your App for API Access, you'll need to provide an "Authorization URL". This should be a URL on your system that we will link to during app installation so you can initiate OAuth and store the returned access tokens. We will link the user to this URL with a redirect query param, e.g. ?redirect=https://app.convertkit.com/apps. When the authorization flow is complete, you need to redirect the user back to that provided redirect URL so they can continue their session within the ConvertKit app.

If you are building a Single Page App (SPA) or mobile app, you'll need to use the Proof Key for Code Exchange (PKCE) flow.

Get an authorization code grant

Code samples

# You can also use wget
curl -G GET https://app.convertkit.com/oauth/authorize \
  -H 'Accept: text/html'
  -d "client_id=string"
  -d "response_type=code"
  -d "redirect_uri=string"

const headers = {
  'Accept':'text/html'
};

fetch('https://app.convertkit.com/oauth/authorize?client_id=string&response_type=code&redirect_uri=string',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'text/html'
}

result = RestClient.get 'https://app.convertkit.com/oauth/authorize?client_id=string&response_type=code&redirect_uri=string',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'text/html'
}

r = requests.get('https://app.convertkit.com/oauth/authorize?client_id=string&response_type=code&redirect_uri=string', headers = headers)

print(r.json())

GET https://app.convertkit.com/oauth/authorize

Parameters

Name In Type Required Description
client_id query string true Your app's client id
response_type query string true code
redirect_uri query string true Uri to redirect to (must be one of your app's redirect uris)
scope query string false Default scope is public. Fine-grained access control via scopes coming soon.
state query string false Custom state to pass to the redirect_uri and/or to protect from XSRF

Example responses

302 Response

"<html><body>You are being <a href=\"https://convertkit.dev/callback?code=mrApixZzMPnYO28KoeIZxn2mvom1Tx48S9iyrQVYVE8\">redirected</a>.</body></html>"

Responses

Status Meaning Description Schema
302 Found Redirects to application redirect_uri with authorization code parameter string

Get a new token using an authorization code

Code samples

# You can also use wget
curl -X POST https://api.convertkit.com/oauth/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -H 'Accept: application/json'

const inputBody = '{
  "client_id": "string",
  "client_secret": "string",
  "grant_type": "authorization_code",
  "code": "string",
  "redirect_uri": "string"
}';
const headers = {
  'Content-Type':'application/x-www-form-urlencoded',
  'Accept':'application/json'
};

fetch('https://api.convertkit.com/oauth/token',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/x-www-form-urlencoded',
  'Accept' => 'application/json'
}

result = RestClient.post 'https://api.convertkit.com/oauth/token',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/x-www-form-urlencoded',
  'Accept': 'application/json'
}

r = requests.post('https://api.convertkit.com/oauth/token', headers = headers)

print(r.json())

POST https://api.convertkit.com/oauth/token

Body parameter

client_id: string
client_secret: string
grant_type: authorization_code
code: string
redirect_uri: string

Parameters

Name In Type Required Description
body body object false none
» client_id body string true Your app's client id
» client_secret body string true Your app's client secret
» grant_type body string true authorization_code
» code body string true The code received via the redirect uri query params
» redirect_uri body string true The redirect uri the request is coming from (must be one of your app's redirect uris)

Example responses

200 Response

{
  "access_token": "YOUR_ACCESS_TOKEN_HERE",
  "token_type": "Bearer",
  "expires_in": 172800,
  "refresh_token": "YOUR_REFRESH_TOKEN_HERE",
  "scope": "public",
  "created_at": 1710270147
}

Responses

Status Meaning Description Schema
200 OK Returns a token Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» access_token string true none none
» token_type string true none none
» expires_in integer true none none
» refresh_token string true none none
» scope string true none none
» created_at integer true none none

Get a new token using a refresh token

Code samples

# You can also use wget
curl -X POST https://api.convertkit.com/oauth/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -H 'Accept: application/json'

const inputBody = '{
  "client_id": "string",
  "grant_type": "refresh_token",
  "refresh_token": "string"
}';
const headers = {
  'Content-Type':'application/x-www-form-urlencoded',
  'Accept':'application/json'
};

fetch('https://api.convertkit.com/oauth/token',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/x-www-form-urlencoded',
  'Accept' => 'application/json'
}

result = RestClient.post 'https://api.convertkit.com/oauth/token',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/x-www-form-urlencoded',
  'Accept': 'application/json'
}

r = requests.post('https://api.convertkit.com/oauth/token', headers = headers)

print(r.json())

POST /oauth/token

Body parameter

client_id: string
grant_type: refresh_token
refresh_token: string

Parameters

Name In Type Required Description
body body object false none
» client_id body string true Your app's client id
» grant_type body string true refresh_token
» refresh_token body string true The refresh token

Example responses

200 Response

{
  "access_token": "YOUR_NEW_ACCESS_TOKEN_HERE",
  "token_type": "Bearer",
  "expires_in": 7200,
  "refresh_token": "YOUR_NEW_REFRESH_TOKEN_HERE",
  "scope": "public",
  "created_at": 1710271006
}

Responses

Status Meaning Description Schema
200 OK Returns a token Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» access_token string true none none
» token_type string true none none
» expires_in integer true none none
» refresh_token string true none none
» scope string true none none
» created_at integer true none none

[PKCE] Get an authorization code grant

Code samples

# You can also use wget
curl -G GET https://app.convertkit.com/oauth/authorize \
  -H 'Accept: text/html'
  -d "client_id=string"
  -d "response_type=code"
  -d "redirect_uri=string"

const headers = {
  'Accept':'text/html'
};

fetch('https://app.convertkit.com/oauth/authorize?client_id=string&response_type=code&redirect_uri=string&code_challenge=string&code_challenge_method=S256',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'text/html'
}

result = RestClient.get 'https://app.convertkit.com/oauth/authorize?client_id=string&response_type=code&redirect_uri=string&code_challenge=string&code_challenge_method=S256',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'text/html'
}

r = requests.get('https://app.convertkit.com/oauth/authorize?client_id=string&response_type=code&redirect_uri=string&code_challenge=string&code_challenge_method=S256', headers = headers)

print(r.json())

GET https://app.convertkit.com/oauth/authorize

Before redirecting the user to the authorization server, the client first generates a secret code verifier and challenge.

The code verifier is a cryptographically random string using the characters A-Z, a-z, 0-9, and the punctuation characters -._~ (hyphen, period, underscore, and tilde), between 43 and 128 characters long.

Once the client has generated the code verifier, it uses that to create the code challenge. The code challenge is a BASE64-URL-encoded string of the SHA256 hash of the code verifier.

The client needs to store the code_verifier for later use.

Parameters

Name In Type Required Description
client_id query string true Your app's client id
response_type query string true code
redirect_uri query string true Uri to redirect to (must be one of your app's redirect uris)
code_challenge query string true A BASE64-URL-encoded string of the SHA256 hash of the code_verifier
code_challenge_method query string true S256
scope query string false Default scope is public. Fine-grained access control via scopes coming soon.
state query string false Custom state to pass to the redirect_uri and/or to protect from XSRF

Example responses

302 Response

"<html><body>You are being <a href=\"https://convertkit.dev/callback?code=mrApixZzMPnYO28KoeIZxn2mvom1Tx48S9iyrQVYVE8\">redirected</a>.</body></html>"

Responses

Status Meaning Description Schema
302 Found Redirects to application redirect_uri with authorization code parameter string

[PKCE] Get a new token using an authorization code and verifier

Code samples

# You can also use wget
curl -X POST https://api.convertkit.com/oauth/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -H 'Accept: application/json'

const inputBody = '{
  "client_id": "string",
  "grant_type": "authorization_code",
  "redirect_uri": "string",
  "code": "string",
  "code_verifier": "string"
}';
const headers = {
  'Content-Type':'application/x-www-form-urlencoded',
  'Accept':'application/json'
};

fetch('https://api.convertkit.com/oauth/token',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/x-www-form-urlencoded',
  'Accept' => 'application/json'
}

result = RestClient.post 'https://api.convertkit.com/oauth/token',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/x-www-form-urlencoded',
  'Accept': 'application/json'
}

r = requests.post('https://api.convertkit.com/oauth/token', headers = headers)

print(r.json())

POST https://api.convertkit.com/oauth/token

Body parameter

client_id: string
grant_type: authorization_code
redirect_uri: string
code: string
code_verifier: string

Parameters

Name In Type Required Description
body body object false none
» client_id body string true Your app's client id
» grant_type body string true authorization_code
» code body string true The code received via the redirect uri query params
» redirect_uri body string true The redirect uri the request is coming from (must be one of your app's redirect uris)
» code_verifier body string true A cryptographically random string using the characters A-Z, a-z, 0-9, and the punctuation characters -._~ (hyphen, period, underscore, and tilde), between 43 and 128 characters long.

Example responses

200 Response

{
  "access_token": "YOUR_ACCESS_TOKEN_HERE",
  "token_type": "Bearer",
  "expires_in": 172800,
  "refresh_token": "YOUR_REFRESH_TOKEN_HERE",
  "scope": "public",
  "created_at": 1710270147
}

Responses

Status Meaning Description Schema
200 OK Returns a token Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» access_token string true none none
» token_type string true none none
» expires_in integer true none none
» refresh_token string true none none
» scope string true none none
» created_at integer true none none

Responses

When an API call succeeds, the API will return a 2xx HTTP response and a JSON response body.

{ 
  "errors": ["Not Found"] 
}

If there's some error, the API will return an HTTP response in the 4xx or 5xx range and a JSON response body with an errors attribute. errors is an array of strings indicating what the error was.

Pagination

{ 
  "pagination": {
    "has_previous_page": false,
    "has_next_page": true,
    "start_cursor": "WzE0XQ==",
    "end_cursor": "WzEzXQ=="
  }
}

All of our list endpoints are paginated unless noted otherwise.

We provide cursor based pagination.

All paginated endpoints will return a pagination object in the JSON response.

curl -X GET https://api.convertkit.com/v4/broadcasts?per_page=10 \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'

The default page size is 500 results. To change the page size, use the per_page query parameter. The maximum page size allowed is 1000.

curl -X GET https://api.convertkit.com/v4/broadcasts?after=WzEzXQ== \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'

To request the next page of results, use the after query param with the end_cursor value of the response.

curl -X GET https://api.convertkit.com/v4/broadcasts?before=WzE0XQ== \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'

To request the previous page of results, use the before query param with the start_cursor value of the response.

To request the total count of the collection, use the include_total_count query param with a value of true. This will complete another data query to return the total count. Expect a slightly slower response when using this option.

Dates

All dates are returned in UTC, ISO8601 format.

Bad data

When you create or update a field, you may receive an error response with status code 422 if any fields contain bad data or required fields are missing.

Rate limiting

Our rate limit is no more than 120 requests over a rolling 60 second period for a given api key.

If your request rate exceeds our limits, you will receive an error response with status code 429, which your code should gracefully handle. We recommend spacing out your requests and performing an exponential backoff to keep within the limit.

Internal server errors

If the server is overloaded or you encounter a bug, you will receive a response with status code 500. Try again after a short period, and if you continue to encounter an error, please raise the issue with support.

Bulk and async processing

We support bulk processing for some common use cases, e.g. create subscribers. These endpoints exist in the bulk namespace, i.e. https://api.convertkit.com/bulk/.

In our bulk requests, we support synchronous processing for small batch sizes. The cut off size is clearly documented in each bulk request's documentation below.

For large batch sizes, we use an asynchronous callback design. If you include a callback_url in your request body, we’ll POST to that URL when our processing has completed. Our POST request body will be the same response shape as our documented our synchronous 200 OK use case for each endpoint.

If you try to enqueue too many bulk requests at once, you'll receive an error response with a 413 status code, which your code should gracefully handle. Try again after a short period.

ConvertKit API v4.0

Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.

Base URLs:

Authentication

Accounts

Get current account

Code samples

# You can also use wget
curl -X GET https://api.convertkit.com/v4/account \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/account',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.get 'https://api.convertkit.com/v4/account',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.get('https://api.convertkit.com/v4/account', headers = headers)

print(r.json())

GET /v4/account

Parameters

Name In Type Required Description
Authorization header string true none

Example responses

200 Response

{
  "user": {
    "email": "test@convertkit.dev"
  },
  "account": {
    "name": "CK Greetings",
    "plan_type": "creator",
    "primary_email_address": "test@convertkit.dev",
    "created_at": "2023-02-17T11:43:55Z"
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns current account and user info Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» user object true none none
»» email string true none none
» account object true none none
»» name string true none none
»» plan_type string true none none
»» primary_email_address string true none none
»» created_at string false none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

List colors

Code samples

# You can also use wget
curl -X GET https://api.convertkit.com/v4/account/colors \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/account/colors',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.get 'https://api.convertkit.com/v4/account/colors',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.get('https://api.convertkit.com/v4/account/colors', headers = headers)

print(r.json())

GET /v4/account/colors

Parameters

Name In Type Required Description
Authorization header string true none

Example responses

200 Response

{
  "colors": [
    "#008000",
    "#FF0000"
  ]
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns list of colors for the current account Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» colors [string] true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Update colors

Code samples

# You can also use wget
curl -X PUT https://api.convertkit.com/v4/account/colors \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'

const inputBody = '{
  "colors": [
    "string"
  ]
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/account/colors',
{
  method: 'PUT',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.put 'https://api.convertkit.com/v4/account/colors',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.put('https://api.convertkit.com/v4/account/colors', headers = headers)

print(r.json())

PUT /v4/account/colors

Body parameter

{
  "colors": [
    "string"
  ]
}

Parameters

Name In Type Required Description
Authorization header string true none
body body object false none
» colors body [string] true An array of up to 5 color hex codes

Example responses

200 Response

{
  "colors": [
    "#000000",
    "#ffffff"
  ]
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

422 Response

{
  "errors": [
    "Colors #123_not_a_code is not a valid hex color code."
  ]
}

Responses

Status Meaning Description Schema
200 OK Updates and returns list of colors for the current account Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
422 Unprocessable Entity Returns a 422 with an error message when invalid color code is provided Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» colors [string] true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 422

Name Type Required Restrictions Description
» errors [string] true none none

Get Creator Profile

Code samples

# You can also use wget
curl -X GET https://api.convertkit.com/v4/account/creator_profile \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/account/creator_profile',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.get 'https://api.convertkit.com/v4/account/creator_profile',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.get('https://api.convertkit.com/v4/account/creator_profile', headers = headers)

print(r.json())

GET /v4/account/creator_profile

Parameters

Name In Type Required Description
Authorization header string true none

Example responses

200 Response

{
  "profile": {
    "name": "A Creator's Journey",
    "byline": "A Creator",
    "bio": "Follow my Journey as a Creator",
    "image_url": "https://convertkit.dev/image.jpg?fit=crop&h=320&w=320",
    "profile_url": "https://ck-greetings.ck.page/profile"
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

404 Response

{
  "errors": [
    "Not Found"
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns Creator Profile details Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
404 Not Found Returns a 404 if the creator profile doesn't exist Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» profile object true none none
»» name string true none none
»» byline string true none none
»» bio string true none none
»» image_url string true none none
»» profile_url string true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 404

Name Type Required Restrictions Description
» errors [string] true none none

Get email stats

Code samples

# You can also use wget
curl -X GET https://api.convertkit.com/v4/account/email_stats \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/account/email_stats',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.get 'https://api.convertkit.com/v4/account/email_stats',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.get('https://api.convertkit.com/v4/account/email_stats', headers = headers)

print(r.json())

GET /v4/account/email_stats

Parameters

Name In Type Required Description
Authorization header string true none

Example responses

200 Response

{
  "stats": {
    "sent": 6,
    "clicked": 3,
    "opened": 6,
    "email_stats_mode": "last_90",
    "open_tracking_enabled": true,
    "click_tracking_enabled": true,
    "starting": "2022-11-19T11:43:55Z",
    "ending": "2023-02-17T11:43:55Z"
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns your email stats for the last 90 days Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» stats object true none none
»» sent integer true none none
»» clicked integer true none none
»» opened integer true none none
»» email_stats_mode string true none none
»» open_tracking_enabled boolean true none none
»» click_tracking_enabled boolean true none none
»» starting string true none none
»» ending string true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Get growth stats

Code samples

# You can also use wget
curl -X GET https://api.convertkit.com/v4/account/growth_stats \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/account/growth_stats',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.get 'https://api.convertkit.com/v4/account/growth_stats',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.get('https://api.convertkit.com/v4/account/growth_stats', headers = headers)

print(r.json())

GET /v4/account/growth_stats

Get growth stats for a specific time period. Defaults to last 90 days.

NOTE: We return your stats in your sending time zone. This endpoint does not return timestamps in UTC.

Parameters

Name In Type Required Description
Authorization header string true none
ending query string false Get stats for time period ending on this date (format yyyy-mm-dd). Defaults to today.
starting query string false Get stats for time period beginning on this date (format yyyy-mm-dd). Defaults to 90 days ago.

Example responses

200 Response

{
  "stats": {
    "cancellations": 0,
    "net_new_subscribers": 3,
    "new_subscribers": 3,
    "subscribers": 3,
    "starting": "2023-02-10T00:00:00-05:00",
    "ending": "2023-02-24T23:59:59-05:00"
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

422 Response

{
  "errors": [
    "Starting date is incorrectly formatted. Use YYYY-MM-DD.",
    "Ending date is incorrectly formatted. Use YYYY-MM-DD."
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns your growth stats for the provided starting and ending dates Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
422 Unprocessable Entity Returns a 422 with an error message if the starting or ending params are misformatted Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» stats object true none none
»» cancellations integer true none none
»» net_new_subscribers integer true none none
»» new_subscribers integer true none none
»» subscribers integer true none none
»» starting string true none none
»» ending string true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 422

Name Type Required Restrictions Description
» errors [string] true none none

Broadcasts

List broadcasts

Code samples

# You can also use wget
curl -X GET https://api.convertkit.com/v4/broadcasts \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/broadcasts',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.get 'https://api.convertkit.com/v4/broadcasts',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.get('https://api.convertkit.com/v4/broadcasts', headers = headers)

print(r.json())

GET /v4/broadcasts

Parameters

Name In Type Required Description
Authorization header string true none
after query any false To fetch next page of results, use ?after=<end_cursor>
before query any false To fetch previous page of results, use ?before=<start_cursor>
include_total_count query string false To include the total count of records in the response, use true. For large collections, expect a slightly slower response.
per_page query any false Number of results per page. Default 500, maximum 1000.

Example responses

200 Response

{
  "broadcasts": [
    {
      "id": 3,
      "created_at": "2023-02-17T11:43:55Z",
      "subject": "Productivity tricks",
      "preview_text": null,
      "description": null,
      "content": null,
      "public": false,
      "published_at": null,
      "send_at": null,
      "thumbnail_alt": null,
      "thumbnail_url": null,
      "email_address": null,
      "email_template": {
        "id": 6,
        "name": "Text Only"
      },
      "subscriber_filter": [
        {
          "all": [
            {
              "type": "all_subscribers"
            }
          ]
        }
      ]
    },
    {
      "id": 2,
      "created_at": "2023-02-17T11:43:55Z",
      "subject": "5 tips for a less stressful work week",
      "preview_text": null,
      "description": null,
      "content": null,
      "public": false,
      "published_at": null,
      "send_at": "2023-02-17T11:53:55Z",
      "thumbnail_alt": null,
      "thumbnail_url": null,
      "email_address": null,
      "email_template": {
        "id": 6,
        "name": "Text Only"
      },
      "subscriber_filter": [
        {
          "all": [
            {
              "type": "all_subscribers"
            }
          ]
        }
      ]
    },
    {
      "id": 1,
      "created_at": "2023-02-14T11:43:55Z",
      "subject": "You'll never guess...",
      "preview_text": null,
      "description": null,
      "content": null,
      "public": false,
      "published_at": "2023-02-17T11:43:55Z",
      "send_at": "2023-02-17T11:38:55Z",
      "thumbnail_alt": null,
      "thumbnail_url": null,
      "email_address": null,
      "email_template": {
        "id": 6,
        "name": "Text Only"
      },
      "subscriber_filter": [
        {
          "all": [
            {
              "type": "all_subscribers"
            }
          ]
        }
      ]
    }
  ],
  "pagination": {
    "has_previous_page": false,
    "has_next_page": false,
    "start_cursor": "WzNd",
    "end_cursor": "WzFd",
    "per_page": 500
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns a paginated list of all broadcasts for your account (including draft, scheduled, and already sent) Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» broadcasts [object] true none none
»» id integer true none none
»» created_at string true none none
»» subject string true none none
»» description any true none none
»» content any true none none
»» public boolean true none none
»» published_at any true none none
»» send_at any true none none
»» thumbnail_alt any true none none
»» thumbnail_url any true none none
»» email_address any true none none
»» preview_text any false none none
»» email_template object true none none
»»» id integer true none none
»»» name string true none none
»» subscriber_filter [object] true none none
»»» all [object] true none none
»»»» type string true none none
»»»» ids [integer] false none none
»»» any [object] false none none
»»»» type string true none none
»»»» ids [integer] true none none
»»» none [object] false none none
»»»» type string true none none
»»»» ids [integer] true none none
» pagination object true none none
»» has_previous_page boolean true none none
»» has_next_page boolean true none none
»» start_cursor string¦null true none none
»» end_cursor string¦null true none none
»» per_page integer true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Create a broadcast

Code samples

# You can also use wget
curl -X POST https://api.convertkit.com/v4/broadcasts \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'

const inputBody = '{
  "email_template_id": 0,
  "email_address": "string",
  "content": "string",
  "description": "string",
  "public": true,
  "published_at": "string",
  "send_at": "string",
  "thumbnail_alt": "string",
  "thumbnail_url": "string",
  "preview_text": "string",
  "subject": "string",
  "subscriber_filter": [
    {
      "all": [
        {
          "type": "string",
          "ids": [
            0
          ]
        }
      ],
      "any": [
        {
          "type": "string",
          "ids": [
            "string"
          ]
        }
      ],
      "none": [
        {
          "type": "string",
          "ids": [
            "string"
          ]
        }
      ]
    }
  ]
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/broadcasts',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.post 'https://api.convertkit.com/v4/broadcasts',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.post('https://api.convertkit.com/v4/broadcasts', headers = headers)

print(r.json())

POST /v4/broadcasts

Draft or schedule to send a broadcast to all or a subset of your subscribers.

To save a draft, set public to false.

To schedule the broadcast for sending, set public to true and provide send_at. Scheduled broadcasts should contain a subject and your content, at a minimum.

We currently support targeting your subscribers based on segment or tag ids.

Body parameter

{
  "email_template_id": 0,
  "email_address": "string",
  "content": "string",
  "description": "string",
  "public": true,
  "published_at": "string",
  "send_at": "string",
  "thumbnail_alt": "string",
  "thumbnail_url": "string",
  "preview_text": "string",
  "subject": "string",
  "subscriber_filter": [
    {
      "all": [
        {
          "type": "string",
          "ids": [
            0
          ]
        }
      ],
      "any": [
        {
          "type": "string",
          "ids": [
            "string"
          ]
        }
      ],
      "none": [
        {
          "type": "string",
          "ids": [
            "string"
          ]
        }
      ]
    }
  ]
}

Parameters

Name In Type Required Description
Authorization header string true none
body body object false none
» email_template_id body integer¦null true Id of the email template to use. Uses the account's default template if not provided.
» email_address body string¦null true The sending email address to use. Uses the account's sending email address if not provided.
» content body string¦null true The HTML content of the email.
» description body string¦null true none
» public body boolean¦null true true to publish this broadcast. false to save a draft.
» published_at body string¦null true The published timestamp to display in ISO8601 format. If no timezone is provided, UTC is assumed.
» send_at body string¦null true The scheduled send time for this broadcast in ISO8601 format. If no timezone is provided, UTC is assumed.
» thumbnail_alt body string¦null true none
» thumbnail_url body string¦null true none
» preview_text body string¦null true none
» subject body string¦null true none
» subscriber_filter body [object]¦null true Filters your subscribers. At this time, we only support using only one filter group type via the API (e.g. all, any, or none but no combinations). If nothing is provided, will default to all of your subscribers.
»» all body [object]¦null true Filters your subscribers using a logical AND of all provided segment and tag ids, i.e. a subscriber would have to be part of all segments and tags provided
»»» type body string true segment or tag
»»» ids body [integer] true none
»» any body [object]¦null true Filters your subscribers using a logical OR of all provided segment and tag ids, i.e. a subscriber would have to be part of at least one of the segments or tags provided
»»» type body string true segment or tag
»»» ids body [string] true none
»» none body [object]¦null true Filters your subscribers using a logical NOT of all provided segment and tag ids, i.e. a subscriber would have to be in none of the segments or tags provided
»»» type body string true segment or tag
»»» ids body [string] true none

Example responses

201 Response

{
  "broadcast": {
    "id": 15,
    "created_at": "2023-02-17T11:43:55Z",
    "subject": "Hello!",
    "preview_text": "Pleased to meet you!",
    "description": "Intro email",
    "content": "<p>Let me introduce myself</p>",
    "public": true,
    "published_at": "2023-02-17T11:43:55Z",
    "send_at": "2023-02-17T11:43:55Z",
    "thumbnail_alt": null,
    "thumbnail_url": null,
    "email_address": "greetings@convertkit.dev",
    "email_template": {
      "id": 2,
      "name": "Classic"
    },
    "subscriber_filter": [
      {
        "all": [
          {
            "type": "segment",
            "ids": [
              8
            ]
          }
        ]
      }
    ]
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

403 Response

{
  "errors": [
    "You do not have sufficient permissions to access this resource. Please contact support."
  ]
}

422 Response

{
  "errors": [
    "Email template not found",
    "Only a single filter group is supported. Use one of `all`, `any`, or `none`."
  ]
}

Responses

Status Meaning Description Schema
201 Created Creates a new broadcast Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
403 Forbidden Returns a 403 with an error message if the current account is unauthorized to create a broadcast Inline
422 Unprocessable Entity Returns a 422 with an error message when one or more of the parameters were invalid Inline

Response Schema

Status Code 201

Name Type Required Restrictions Description
» broadcast object true none none
»» id integer true none none
»» created_at string true none none
»» subject string true none none
»» preview_text string true none none
»» description string true none none
»» content string true none none
»» public boolean true none none
»» published_at string true none none
»» send_at string true none none
»» thumbnail_alt any true none none
»» thumbnail_url any true none none
»» email_address string true none none
»» email_template object true none none
»»» id integer true none none
»»» name string true none none
»» subscriber_filter [object] true none none
»»» all [object] true none none
»»»» type string true none none
»»»» ids [integer] true none none
»»» any [object] false none none
»»»» type string true none none
»»»» ids [integer] true none none
»»» none [object] false none none
»»»» type string true none none
»»»» ids [integer] true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 403

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 422

Name Type Required Restrictions Description
» errors [string] true none none

Delete a broadcast

Code samples

# You can also use wget
curl -X DELETE https://api.convertkit.com/v4/broadcasts/{id} \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -H 'Accept: ' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'

const inputBody = '{}';
const headers = {
  'Content-Type':'application/x-www-form-urlencoded',
  'Accept':'',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/broadcasts/{id}',
{
  method: 'DELETE',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/x-www-form-urlencoded',
  'Accept' => '',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.delete 'https://api.convertkit.com/v4/broadcasts/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/x-www-form-urlencoded',
  'Accept': '',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.delete('https://api.convertkit.com/v4/broadcasts/{id}', headers = headers)

print(r.json())

DELETE /v4/broadcasts/{id}

Body parameter

{}

Parameters

Name In Type Required Description
Authorization header string true none
id path integer true none
body body object false none

Example responses

204 Response

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

403 Response

{
  "errors": [
    "You do not have sufficient permissions to access this resource. Please contact support."
  ]
}

404 Response

{
  "errors": [
    "Not Found"
  ]
}

422 Response

{
  "errors": [
    "Broadcast is already sending."
  ]
}

Responses

Status Meaning Description Schema
204 No Content Deletes the broadcast string
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
403 Forbidden Returns a 403 with an error message if the current account is unauthorized to update a broadcast Inline
404 Not Found Returns a 404 when the provided id does not exist Inline
422 Unprocessable Entity Returns a 422 with an error message if the broadcast has already started sending or already sent Inline

Response Schema

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 403

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 404

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 422

Name Type Required Restrictions Description
» errors [string] true none none

Get a broadcast

Code samples

# You can also use wget
curl -X GET https://api.convertkit.com/v4/broadcasts/{id} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/broadcasts/{id}',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.get 'https://api.convertkit.com/v4/broadcasts/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.get('https://api.convertkit.com/v4/broadcasts/{id}', headers = headers)

print(r.json())

GET /v4/broadcasts/{id}

Parameters

Name In Type Required Description
Authorization header string true none
id path integer true none

Example responses

200 Response

{
  "broadcast": {
    "id": 11,
    "created_at": "2023-02-17T11:43:55Z",
    "subject": "You'll never guess...",
    "description": null,
    "content": null,
    "public": false,
    "published_at": null,
    "send_at": null,
    "thumbnail_alt": null,
    "thumbnail_url": null,
    "email_address": null,
    "preview_text": null,
    "email_template": {
      "id": 6,
      "name": "Text Only"
    },
    "subscriber_filter": [
      {
        "all": [
          {
            "type": "all_subscribers"
          }
        ]
      }
    ]
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

404 Response

{
  "errors": [
    "Not Found"
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns the broadcast details Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
404 Not Found Returns a 404 when the provided id does not exist Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» broadcast object true none none
»» id integer true none none
»» created_at string true none none
»» subject string true none none
»» description any true none none
»» content any true none none
»» public boolean true none none
»» published_at any true none none
»» send_at any true none none
»» thumbnail_alt any true none none
»» thumbnail_url any true none none
»» email_address any true none none
»» preview_text any false none none
»» email_template object true none none
»»» id integer true none none
»»» name string true none none
»» subscriber_filter [object] true none none
»»» all [object] true none none
»»»» type string true none none
»»»» ids [integer] false none none
»»» any [object] false none none
»»»» type string true none none
»»»» ids [integer] true none none
»»» none [object] false none none
»»»» type string true none none
»»»» ids [integer] true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 404

Name Type Required Restrictions Description
» errors [string] true none none

Update a broadcast

Code samples

# You can also use wget
curl -X PUT https://api.convertkit.com/v4/broadcasts/{id} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'

const inputBody = '{
  "email_template_id": 0,
  "email_address": "string",
  "content": "string",
  "description": "string",
  "public": true,
  "published_at": "string",
  "send_at": "string",
  "thumbnail_alt": "string",
  "thumbnail_url": "string",
  "preview_text": "string",
  "subject": "string",
  "subscriber_filter": [
    {
      "all": [
        {
          "type": "string",
          "ids": [
            0
          ]
        }
      ],
      "any": [
        {
          "type": "string",
          "ids": [
            "string"
          ]
        }
      ],
      "none": [
        {
          "type": "string",
          "ids": [
            "string"
          ]
        }
      ]
    }
  ]
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/broadcasts/{id}',
{
  method: 'PUT',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.put 'https://api.convertkit.com/v4/broadcasts/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.put('https://api.convertkit.com/v4/broadcasts/{id}', headers = headers)

print(r.json())

PUT /v4/broadcasts/{id}

Update an existing broadcast. Continue to draft or schedule to send a broadcast to all or a subset of your subscribers.

To save a draft, set public to false.

To schedule the broadcast for sending, set public to true and provide send_at. Scheduled broadcasts should contain a subject and your content, at a minimum.

We currently support targeting your subscribers based on segment or tag ids.

Body parameter

{
  "email_template_id": 0,
  "email_address": "string",
  "content": "string",
  "description": "string",
  "public": true,
  "published_at": "string",
  "send_at": "string",
  "thumbnail_alt": "string",
  "thumbnail_url": "string",
  "preview_text": "string",
  "subject": "string",
  "subscriber_filter": [
    {
      "all": [
        {
          "type": "string",
          "ids": [
            0
          ]
        }
      ],
      "any": [
        {
          "type": "string",
          "ids": [
            "string"
          ]
        }
      ],
      "none": [
        {
          "type": "string",
          "ids": [
            "string"
          ]
        }
      ]
    }
  ]
}

Parameters

Name In Type Required Description
Authorization header string true none
id path integer true none
body body object false none
» email_template_id body integer¦null true Id of the email template to use. Uses the account's default template if not provided.
» email_address body string¦null true The sending email address to use. Uses the account's sending email address if not provided.
» content body string¦null true The HTML content of the email.
» description body string¦null true none
» public body boolean¦null true true to publish this broadcast. false to save a draft.
» published_at body string¦null true The published timestamp to display in ISO8601 format. If no timezone is provided, UTC is assumed.
» send_at body string¦null true The scheduled send time for this broadcast in ISO8601 format. If no timezone is provided, UTC is assumed.
» thumbnail_alt body string¦null true none
» thumbnail_url body string¦null true none
» preview_text body string¦null true none
» subject body string¦null true none
» subscriber_filter body [object]¦null true Filters your subscribers. At this time, we only support using only one filter group type via the API (e.g. all, any, or none but no combinations). If nothing is provided, will default to all of your subscribers.
»» all body [object]¦null true Filters your subscribers using a logical AND of all provided segment and tag ids, i.e. a subscriber would have to be part of all segments and tags provided
»»» type body string true segment or tag
»»» ids body [integer] true none
»» any body [object]¦null true Filters your subscribers using a logical OR of all provided segment and tag ids, i.e. a subscriber would have to be part of at least one of the segments or tags provided
»»» type body string true segment or tag
»»» ids body [string] true none
»» none body [object]¦null true Filters your subscribers using a logical NOT of all provided segment and tag ids, i.e. a subscriber would have to be in none of the segments or tags provided
»»» type body string true segment or tag
»»» ids body [string] true none

Example responses

200 Response

{
  "broadcast": {
    "id": 28,
    "created_at": "2023-02-17T11:43:55Z",
    "subject": "Hello!",
    "preview_text": "Pleased to meet you!",
    "description": "Intro email",
    "content": "<p>Let me introduce myself</p>",
    "public": true,
    "published_at": "2023-02-17T11:43:55Z",
    "send_at": "2023-02-17T11:43:55Z",
    "thumbnail_alt": null,
    "thumbnail_url": null,
    "email_address": "greetings@convertkit.dev",
    "email_template": {
      "id": 2,
      "name": "Classic"
    },
    "subscriber_filter": [
      {
        "all": [
          {
            "type": "segment",
            "ids": [
              23
            ]
          }
        ]
      }
    ]
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

403 Response

{
  "errors": [
    "You do not have sufficient permissions to access this resource. Please contact support."
  ]
}

404 Response

{
  "errors": [
    "Not Found"
  ]
}

422 Response

{
  "errors": [
    "Email template not found",
    "Only a single filter group is supported. Use one of `all`, `any`, or `none`."
  ]
}

Responses

Status Meaning Description Schema
200 OK Updates the broadcast and returns its details Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
403 Forbidden Returns a 403 with an error message if the current account is unauthorized to create a broadcast Inline
404 Not Found Returns a 404 when the provided id does not exist Inline
422 Unprocessable Entity Returns a 422 with an error message when one or more of the parameters are invalid or the campaign has already started sending Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» broadcast object true none none
»» id integer true none none
»» created_at string true none none
»» subject string true none none
»» preview_text string true none none
»» description string true none none
»» content string true none none
»» public boolean true none none
»» published_at string true none none
»» send_at string true none none
»» thumbnail_alt any true none none
»» thumbnail_url any true none none
»» email_address string true none none
»» email_template object true none none
»»» id integer true none none
»»» name string true none none
»» subscriber_filter [object] true none none
»»» all [object] true none none
»»»» type string true none none
»»»» ids [integer] true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 403

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 404

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 422

Name Type Required Restrictions Description
» errors [string] true none none

Get stats

Code samples

# You can also use wget
curl -X GET https://api.convertkit.com/v4/broadcasts/{id}/stats \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/broadcasts/{id}/stats',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.get 'https://api.convertkit.com/v4/broadcasts/{id}/stats',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.get('https://api.convertkit.com/v4/broadcasts/{id}/stats', headers = headers)

print(r.json())

GET /v4/broadcasts/{id}/stats

Parameters

Name In Type Required Description
Authorization header string true none
id path integer true none

Example responses

200 Response

{
  "broadcast": {
    "id": 61,
    "stats": {
      "recipients": 0,
      "open_rate": 0,
      "click_rate": 0,
      "unsubscribes": 0,
      "total_clicks": 0,
      "show_total_clicks": false,
      "status": "draft",
      "progress": 0,
      "open_tracking_disabled": false,
      "click_tracking_disabled": false
    }
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

404 Response

{
  "errors": [
    "Not Found"
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns stats for a broadcast Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
404 Not Found Returns a 404 when the provided id does not exist Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» broadcast object true none none
»» id integer true none none
»» stats object true none none
»»» recipients integer true none none
»»» open_rate number(float) true none none
»»» click_rate number(float) true none none
»»» unsubscribes integer true none none
»»» total_clicks integer true none none
»»» show_total_clicks boolean true none none
»»» status string true none none
»»» progress number(float) true none none
»»» open_tracking_disabled boolean true none none
»»» click_tracking_disabled boolean true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 404

Name Type Required Restrictions Description
» errors [string] true none none

Custom Fields

Bulk create custom fields

Code samples

# You can also use wget
curl -X POST https://api.convertkit.com/v4/bulk/custom_fields \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'

const inputBody = '{
  "custom_fields": [
    {
      "label": "string"
    }
  ],
  "callback_url": null
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/bulk/custom_fields',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.post 'https://api.convertkit.com/v4/bulk/custom_fields',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.post('https://api.convertkit.com/v4/bulk/custom_fields', headers = headers)

print(r.json())

POST /v4/bulk/custom_fields

Body parameter

{
  "custom_fields": [
    {
      "label": "string"
    }
  ],
  "callback_url": null
}

Parameters

Name In Type Required Description
Authorization header string true none
body body object false none
» custom_fields body [object] true none
»» label body string true none
» callback_url body any false none

Example responses

200 Response

{
  "custom_fields": [
    {
      "id": 46,
      "label": "Interests",
      "key": "interests",
      "name": "ck_field_46_interests",
      "created_at": "2023-02-17T11:43:55Z"
    },
    {
      "id": 45,
      "label": "Last name",
      "key": "last_name",
      "name": "ck_field_45_last_name",
      "created_at": "2023-02-17T11:43:55Z"
    }
  ],
  "failures": [
    {
      "custom_field": {
        "id": 44,
        "label": "Existing Custom Field",
        "key": "existing_custom_field",
        "name": "ck_field_44_existing_custom_field",
        "created_at": "2023-02-17T11:43:55Z"
      },
      "errors": [
        "Label has already been taken"
      ]
    }
  ]
}

202 Response

{}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

413 Response

{
  "errors": [
    "This request exceeds your queued bulk requests limit. Please wait while we process your existing requests and try again later."
  ]
}

422 Response

{
  "errors": [
    "No custom fields included for processing"
  ]
}

Responses

Status Meaning Description Schema
200 OK Creates the custom_fields synchronously when 100 or less custom fields are requested Inline
202 Accepted Creates or updates custom_fields asynchronously when more than 100 custom fields are requested Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
413 Payload Too Large Returns a 413 when the size of the request would exceed the account's data limit for enqueued bulk requests Inline
422 Unprocessable Entity Returns a 422 when custom_fields is empty or not an array Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» custom_fields [object] true none none
»» id integer true none none
»» label string true none none
»» key string true none none
»» name string true none none
»» created_at string true none none
» failures [object] true none none
»» custom_field object true none none
»»» id integer true none none
»»» label string true none none
»»» key string true none none
»»» name string true none none
»»» created_at string true none none
»» errors [string] true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 413

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 422

Name Type Required Restrictions Description
» errors [string] true none none

List custom fields

Code samples

# You can also use wget
curl -X GET https://api.convertkit.com/v4/custom_fields \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/custom_fields',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.get 'https://api.convertkit.com/v4/custom_fields',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.get('https://api.convertkit.com/v4/custom_fields', headers = headers)

print(r.json())

GET /v4/custom_fields

A custom field allows you to collect subscriber information beyond the standard fields of first name and email address. An example would be a custom field called last name so you can get the full names of your subscribers.

You create a custom field, and then you're able to use that in your forms or emails.

Parameters

Name In Type Required Description
Authorization header string true none
after query any false To fetch next page of results, use ?after=<end_cursor>
before query any false To fetch previous page of results, use ?before=<start_cursor>
include_total_count query string false To include the total count of records in the response, use true. For large collections, expect a slightly slower response.
per_page query any false Number of results per page. Default 500, maximum 1000.

Example responses

200 Response

{
  "custom_fields": [
    {
      "id": 1,
      "name": "ck_field_1_last_name",
      "key": "last_name",
      "label": "Last name"
    }
  ],
  "pagination": {
    "has_previous_page": false,
    "has_next_page": false,
    "start_cursor": "WzFd",
    "end_cursor": "WzFd",
    "per_page": 500
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns a paginated list of all custom fields for your account Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» custom_fields [object] true none none
»» id integer true none none
»» name string true none none
»» key string true none none
»» label string true none none
» pagination object true none none
»» has_previous_page boolean true none none
»» has_next_page boolean true none none
»» start_cursor string¦null true none none
»» end_cursor string¦null true none none
»» per_page integer true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Create a custom field

Code samples

# You can also use wget
curl -X POST https://api.convertkit.com/v4/custom_fields \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'

const inputBody = '{
  "label": "string"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/custom_fields',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.post 'https://api.convertkit.com/v4/custom_fields',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.post('https://api.convertkit.com/v4/custom_fields', headers = headers)

print(r.json())

POST /v4/custom_fields

Create a custom field for your account. The label field must be unique to your account. Whitespace will be removed from the beginning and the end of your label.

Additionally, a key field and a name field will be generated for you. The key is an ASCII-only, lowercased, underscored representation of your label. This key must be unique to your account. Keys are used in personalization tags in sequences and broadcasts. Names are unique identifiers for use in the HTML of custom forms. They are made up of a combination of ID and the key of the custom field prefixed with "ck_field".

Body parameter

{
  "label": "string"
}

Parameters

Name In Type Required Description
Authorization header string true none
body body object false none
» label body string true none

Example responses

201 Response

{
  "custom_field": {
    "id": 4,
    "name": "ck_field_4_interests",
    "key": "interests",
    "label": "Interests"
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

422 Response

{
  "errors": [
    "Label can't be blank"
  ]
}

Responses

Status Meaning Description Schema
201 Created Creates a new custom field and returns its details Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
422 Unprocessable Entity Returns a 422 with an error message when the label is missing Inline

Response Schema

Status Code 201

Name Type Required Restrictions Description
» custom_field object true none none
»» id integer true none none
»» name string true none none
»» key string true none none
»» label string true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 422

Name Type Required Restrictions Description
» errors [string] true none none

Delete custom field

Code samples

# You can also use wget
curl -X DELETE https://api.convertkit.com/v4/custom_fields/{id} \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -H 'Accept: ' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'

const inputBody = '{}';
const headers = {
  'Content-Type':'application/x-www-form-urlencoded',
  'Accept':'',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/custom_fields/{id}',
{
  method: 'DELETE',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/x-www-form-urlencoded',
  'Accept' => '',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.delete 'https://api.convertkit.com/v4/custom_fields/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/x-www-form-urlencoded',
  'Accept': '',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.delete('https://api.convertkit.com/v4/custom_fields/{id}', headers = headers)

print(r.json())

DELETE /v4/custom_fields/{id}

This will remove all data in this field from your subscribers.

Body parameter

{}

Parameters

Name In Type Required Description
Authorization header string true none
id path integer true none
body body object false none

Example responses

204 Response

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

404 Response

{
  "errors": [
    "Not Found"
  ]
}

422 Response

{
  "errors": [
    "Unable to destroy the custom field."
  ]
}

Responses

Status Meaning Description Schema
204 No Content Deletes the custom field string
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
404 Not Found Returns a 404 when the provided id does not exist Inline
422 Unprocessable Entity Returns a 422 when the custom field cannot be deleted Inline

Response Schema

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 404

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 422

Name Type Required Restrictions Description
» errors [string] true none none

Update a custom field

Code samples

# You can also use wget
curl -X PUT https://api.convertkit.com/v4/custom_fields/{id} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'

const inputBody = '{
  "label": "string"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/custom_fields/{id}',
{
  method: 'PUT',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.put 'https://api.convertkit.com/v4/custom_fields/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.put('https://api.convertkit.com/v4/custom_fields/{id}', headers = headers)

print(r.json())

PUT /v4/custom_fields/{id}

Updates a custom field label (see Create a custom field above for more information on labels). Note that the key will change but the name remains the same when the label is updated.

Warning: An update to a custom field will break all of the liquid personalization tags in emails that reference it - e.g. if you update a Zip_Code custom field to Post_Code, all liquid tags referencing {{ subscriber.Zip_Code }} would no longer work and need to be replaced with {{ subscriber.Post_Code }}.

Body parameter

{
  "label": "string"
}

Parameters

Name In Type Required Description
Authorization header string true none
id path integer true none
body body object false none
» label body string true none

Example responses

200 Response

{
  "custom_field": {
    "id": 12,
    "name": "ck_field_12_last_name",
    "key": "last_name",
    "label": "Last name"
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

404 Response

{
  "errors": [
    "Not Found"
  ]
}

422 Response

{
  "errors": [
    "Label can't be blank"
  ]
}

Responses

Status Meaning Description Schema
200 OK Updates the custom field and returns its details Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
404 Not Found Returns a 404 when the provided id does not exist Inline
422 Unprocessable Entity Returns a 422 with an error mesage when one or more of the parameters are invalid Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» custom_field object true none none
»» id integer true none none
»» name string true none none
»» key string true none none
»» label string true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 404

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 422

Name Type Required Restrictions Description
» errors [string] true none none

Subscribers

Bulk create subscribers

Code samples

# You can also use wget
curl -X POST https://api.convertkit.com/v4/bulk/subscribers \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'

const inputBody = '{
  "subscribers": [
    {
      "first_name": "string",
      "email_address": "string"
    }
  ],
  "callback_url": null
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/bulk/subscribers',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.post 'https://api.convertkit.com/v4/bulk/subscribers',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.post('https://api.convertkit.com/v4/bulk/subscribers', headers = headers)

print(r.json())

POST /v4/bulk/subscribers

Please see the note about "Bulk and async processing" for more information.

Body parameter

{
  "subscribers": [
    {
      "first_name": "string",
      "email_address": "string"
    }
  ],
  "callback_url": null
}

Parameters

Name In Type Required Description
Authorization header string true none
body body object false none
» subscribers body [object] true none
»» first_name body string true none
»» email_address body string true none
» callback_url body any false none

Example responses

200 Response

{
  "subscribers": [
    {
      "id": 258,
      "first_name": null,
      "email_address": "benito@convertkit.dev",
      "state": "active",
      "created_at": "2023-02-17T11:43:55Z"
    },
    {
      "id": 259,
      "first_name": "Camille",
      "email_address": "camille@convertkit.dev",
      "state": "active",
      "created_at": "2023-02-17T11:43:55Z"
    },
    {
      "id": 257,
      "first_name": "Alice",
      "email_address": "alice@convertkit.dev",
      "state": "active",
      "created_at": "2023-02-17T11:43:55Z"
    }
  ],
  "failures": [
    {
      "subscriber": {
        "first_name": "Benito",
        "email_address": null,
        "state": "active",
        "created_at": null
      },
      "errors": [
        "Email address is invalid"
      ]
    }
  ]
}

202 Response

{}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

403 Response

{
  "errors": [
    "This request would exceed your subscriber limit"
  ]
}

413 Response

{
  "errors": [
    "This request exceeds your queued bulk requests limit. Please wait while we process your existing requests and try again later."
  ]
}

422 Response

{
  "errors": [
    "No subscribers included for processing"
  ]
}

Responses

Status Meaning Description Schema
200 OK Creates or updates the subscribers synchronously when 100 or less subscribers are requested Inline
202 Accepted Creates or updates subscribers asynchronously when more than 100 subscribers are requested Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
403 Forbidden Returns a 403 when the number of subscribers in the request would exceed the account's subscriber limit Inline
413 Payload Too Large Returns a 413 when the size of the request would exceed the account's data limit for enqueued bulk requests Inline
422 Unprocessable Entity Returns a 422 when subscribers is empty or not an array Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» subscribers [object] true none none
»» id integer true none none
»» first_name any true none none
»» email_address string true none none
»» state string true none none
»» created_at string false none none
» failures [object] true none none
»» subscriber object true none none
»»» first_name string true none none
»»» email_address any true none none
»»» state string true none none
»»» created_at any false none none
»» errors [string] true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 403

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 413

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 422

Name Type Required Restrictions Description
» errors [string] true none none

List subscribers

Code samples

# You can also use wget
curl -X GET https://api.convertkit.com/v4/subscribers \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/subscribers',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.get 'https://api.convertkit.com/v4/subscribers',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.get('https://api.convertkit.com/v4/subscribers', headers = headers)

print(r.json())

GET /v4/subscribers

Parameters

Name In Type Required Description
Authorization header string true none
after query any false To fetch next page of results, use ?after=<end_cursor>
before query any false To fetch previous page of results, use ?before=<start_cursor>
created_after query string false Filter subscribers who have been created after this date (format yyyy-mm-dd)
created_before query string false Filter subscribers who have been created before this date (format yyyy-mm-dd)
email_address query string false Search subscribers by email address. This is an exact match search.
include_total_count query string false To include the total count of records in the response, use true. For large collections, expect a slightly slower response.
per_page query any false Number of results per page. Default 500, maximum 1000.
sort_field query string false Field to sort by (id, updated_at, cancelled_at). Defaults to id.
sort_order query string false Sort order for results (asc or desc). Defaults to desc.
status query string false Filter subscribers who have this status (active, inactive, bounced, complained, cancelled or all). Defaults to active.
updated_after query string false Filter subscribers who have been updated after this date (format yyyy-mm-dd)
updated_before query string false Filter subscribers who have been updated before this date (format yyyy-mm-dd)

Example responses

200 Response

{
  "subscribers": [
    {
      "id": 139,
      "first_name": "Alice",
      "email_address": "alice@convertkit.dev",
      "state": "active",
      "created_at": "2023-01-27T11:43:55Z",
      "fields": {
        "category": "One"
      }
    }
  ],
  "pagination": {
    "has_previous_page": false,
    "has_next_page": false,
    "start_cursor": "WzEzOV0=",
    "end_cursor": "WzEzOV0=",
    "per_page": 500
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

422 Response

{
  "errors": [
    "The status param must be `cancelled` if sort_field is `cancelled_at`"
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns a list of subscribers matching the sort and filter params, defaulting to active subscribers sorted in descending order by id Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
422 Unprocessable Entity raises an error when sorting on cancelled_at without the cancelled status Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» subscribers [object] true none none
»» id integer true none none
»» first_name string true none none
»» email_address string true none none
»» state string true none none
»» created_at string true none none
»» fields object true none none
»»» category string true none none
» pagination object true none none
»» has_previous_page boolean true none none
»» has_next_page boolean true none none
»» start_cursor string¦null true none none
»» end_cursor string¦null true none none
»» per_page integer true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 422

Name Type Required Restrictions Description
» errors [string] true none none

Create a subscriber

Code samples

# You can also use wget
curl -X POST https://api.convertkit.com/v4/subscribers \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'

const inputBody = '{
  "first_name": "string",
  "email_address": "string",
  "state": "string",
  "fields": {
    "Last name": "string",
    "Birthday": "string",
    "Source": "string",
    "Role": "string",
    "Company": "string",
    "Postal code": "string",
    "Website": "string",
    "Social media": "string",
    "How did you hear about us?": "string",
    "Interests": "string",
    "Coupon": "string"
  }
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/subscribers',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.post 'https://api.convertkit.com/v4/subscribers',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.post('https://api.convertkit.com/v4/subscribers', headers = headers)

print(r.json())

POST /v4/subscribers

Behaves as an upsert. If a subscriber with the provided email address does not exist, it creates one with the specified first name and state. If a subscriber with the provided email address already exists, it updates the first name.

We will ignore custom fields that don't already exist in your account. We will not return an error if you try to add data to a custom field that does not exist. Please use Create a custom field to create custom fields before setting for subscribers.

NOTE: Updating the subscriber state with this endpoint is not supported at this time.
NOTE: We support creating/updating a maximum of 140 custom fields at a time.

Body parameter

{
  "first_name": "string",
  "email_address": "string",
  "state": "string",
  "fields": {
    "Last name": "string",
    "Birthday": "string",
    "Source": "string",
    "Role": "string",
    "Company": "string",
    "Postal code": "string",
    "Website": "string",
    "Social media": "string",
    "How did you hear about us?": "string",
    "Interests": "string",
    "Coupon": "string"
  }
}

Parameters

Name In Type Required Description
Authorization header string true none
body body object false none
» first_name body string¦null false none
» email_address body string true none
» state body string¦null false Create subscriber in this state (active, bounced, cancelled, complained or inactive). Defaults to active.
» fields body object¦null false none
»» Last name body string true none
»» Birthday body string true none
»» Source body string true none
»» Role body string false none
»» Company body string false none
»» Postal code body string false none
»» Website body string false none
»» Social media body string false none
»» How did you hear about us? body string false none
»» Interests body string false none
»» Coupon body string false none

Example responses

200 Response

{
  "subscriber": {
    "id": 240,
    "first_name": "Alice",
    "email_address": "alice@convertkit.dev",
    "state": "inactive",
    "created_at": "2023-02-17T11:43:55Z",
    "fields": {}
  }
}

201 Response

{
  "subscriber": {
    "id": 238,
    "first_name": "Alice",
    "email_address": "alice@convertkit.dev",
    "state": "active",
    "created_at": "2023-02-17T11:43:55Z",
    "fields": {}
  }
}

202 Response

{
  "subscriber": {
    "id": 239,
    "first_name": "Alice",
    "email_address": "alice@convertkit.dev",
    "state": "active",
    "created_at": "2023-02-17T11:43:55Z",
    "fields": {}
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

422 Response

{
  "errors": [
    "Email address is invalid"
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns a 200 and updates the subscriber first name when a subscriber with provided email already exists Inline
201 Created Creates a new subscriber Inline
202 Accepted Returns a 202 and asynchronously adds custom fields for the new subscriber when more than 10 custom fields are included in the request Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
422 Unprocessable Entity Returns a 422 with an error message when one or more of the parameters are invalid Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» subscriber object true none none
»» id integer true none none
»» first_name string true none none
»» email_address string true none none
»» state string true none none
»» created_at string true none none
»» fields object true none none

Status Code 201

Name Type Required Restrictions Description
» subscriber object true none none
»» id integer true none none
»» first_name string true none none
»» email_address string true none none
»» state string true none none
»» created_at string true none none
»» fields object true none none

Status Code 202

Name Type Required Restrictions Description
» subscriber object true none none
»» id integer true none none
»» first_name string true none none
»» email_address string true none none
»» state string true none none
»» created_at string true none none
»» fields object true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 422

Name Type Required Restrictions Description
» errors [string] true none none

Get a subscriber

Code samples

# You can also use wget
curl -X GET https://api.convertkit.com/v4/subscribers/{id} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/subscribers/{id}',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.get 'https://api.convertkit.com/v4/subscribers/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.get('https://api.convertkit.com/v4/subscribers/{id}', headers = headers)

print(r.json())

GET /v4/subscribers/{id}

Parameters

Name In Type Required Description
Authorization header string true none
id path integer true none

Example responses

200 Response

{
  "subscriber": {
    "id": 224,
    "first_name": "Alice",
    "email_address": "alice@convertkit.dev",
    "state": "active",
    "created_at": "2023-02-17T11:43:55Z",
    "fields": {
      "category": "One"
    }
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

404 Response

{
  "errors": [
    "Not Found"
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns the subscriber details Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
404 Not Found Returns a 404 when the provided id does not exist Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» subscriber object true none none
»» id integer true none none
»» first_name string true none none
»» email_address string true none none
»» state string true none none
»» created_at string true none none
»» fields object true none none
»»» category string true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 404

Name Type Required Restrictions Description
» errors [string] true none none

Update a subscriber

Code samples

# You can also use wget
curl -X PUT https://api.convertkit.com/v4/subscribers/{id} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'

const inputBody = '{
  "first_name": "string",
  "email_address": "string",
  "fields": {
    "Last name": "string",
    "Birthday": "string",
    "Source": "string",
    "Role": "string",
    "Company": "string",
    "Postal code": "string",
    "Website": "string",
    "Social media": "string",
    "How did you hear about us?": "string",
    "Interests": "string",
    "Coupon": "string"
  }
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/subscribers/{id}',
{
  method: 'PUT',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.put 'https://api.convertkit.com/v4/subscribers/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.put('https://api.convertkit.com/v4/subscribers/{id}', headers = headers)

print(r.json())

PUT /v4/subscribers/{id}

We will ignore custom fields that don't already exist in your account. We will not return an error if you try to add data to a custom field that does not exist. Please use Create a custom field to create custom fields before setting for subscribers.

NOTE: We support creating/updating a maximum of 140 custom fields at a time.

Body parameter

{
  "first_name": "string",
  "email_address": "string",
  "fields": {
    "Last name": "string",
    "Birthday": "string",
    "Source": "string",
    "Role": "string",
    "Company": "string",
    "Postal code": "string",
    "Website": "string",
    "Social media": "string",
    "How did you hear about us?": "string",
    "Interests": "string",
    "Coupon": "string"
  }
}

Parameters

Name In Type Required Description
Authorization header string true none
id path integer true none
body body object false none
» first_name body string¦null false none
» email_address body string true none
» fields body object¦null false none
»» Last name body string true none
»» Birthday body string true none
»» Source body string true none
»» Role body string false none
»» Company body string false none
»» Postal code body string false none
»» Website body string false none
»» Social media body string false none
»» How did you hear about us? body string false none
»» Interests body string false none
»» Coupon body string false none

Example responses

200 Response

{
  "subscriber": {
    "id": 250,
    "first_name": "Alice",
    "email_address": "alice@convertkit.dev",
    "state": "active",
    "created_at": "2023-02-17T11:43:55Z",
    "fields": {}
  }
}

202 Response

{
  "subscriber": {
    "id": 251,
    "first_name": "Alice",
    "email_address": "alice@convertkit.dev",
    "state": "active",
    "created_at": "2023-02-17T11:43:55Z",
    "fields": {}
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

404 Response

{
  "errors": [
    "Not Found"
  ]
}

422 Response

{
  "errors": [
    "Email address has already been taken"
  ]
}

Responses

Status Meaning Description Schema
200 OK Updates the subscriber's email address and first name Inline
202 Accepted Returns a 202 and asynchronously updates custom fields for the subscriber when more than 10 custom fields are included in the request Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
404 Not Found Returns a 404 when the provided id does not exist Inline
422 Unprocessable Entity Returns 422 with an error when email address is already in use Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» subscriber object true none none
»» id integer true none none
»» first_name string true none none
»» email_address string true none none
»» state string true none none
»» created_at string true none none
»» fields object true none none

Status Code 202

Name Type Required Restrictions Description
» subscriber object true none none
»» id integer true none none
»» first_name string true none none
»» email_address string true none none
»» state string true none none
»» created_at string true none none
»» fields object true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 404

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 422

Name Type Required Restrictions Description
» errors [string] true none none

Unsubscribe subscriber

Code samples

# You can also use wget
curl -X POST https://api.convertkit.com/v4/subscribers/{id}/unsubscribe \
  -H 'Content-Type: application/json' \
  -H 'Accept: ' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'

const inputBody = '{}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/subscribers/{id}/unsubscribe',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => '',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.post 'https://api.convertkit.com/v4/subscribers/{id}/unsubscribe',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': '',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.post('https://api.convertkit.com/v4/subscribers/{id}/unsubscribe', headers = headers)

print(r.json())

POST /v4/subscribers/{id}/unsubscribe

Body parameter

{}

Parameters

Name In Type Required Description
Authorization header string true none
id path integer true none
body body object false none

Example responses

204 Response

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

404 Response

{
  "errors": [
    "Not Found"
  ]
}

Responses

Status Meaning Description Schema
204 No Content Unsubscribes the subscriber string
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
404 Not Found Returns a 404 when the provided id does not exist Inline

Response Schema

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 404

Name Type Required Restrictions Description
» errors [string] true none none

List tags for a subscriber

Code samples

# You can also use wget
curl -X GET https://api.convertkit.com/v4/subscribers/{subscriber_id}/tags \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/subscribers/{subscriber_id}/tags',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.get 'https://api.convertkit.com/v4/subscribers/{subscriber_id}/tags',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.get('https://api.convertkit.com/v4/subscribers/{subscriber_id}/tags', headers = headers)

print(r.json())

GET /v4/subscribers/{subscriber_id}/tags

Parameters

Name In Type Required Description
Authorization header string true none
after query any false none
before query any false none
include_total_count query string false To include the total count of records in the response, use true. For large collections, expect a slightly slower response.
per_page query any false none
subscriber_id path integer true none

Example responses

200 Response

{
  "tags": [
    {
      "id": 43,
      "name": "Tag A",
      "tagged_at": "2023-02-17T10:43:55Z"
    },
    {
      "id": 42,
      "name": "Tag B",
      "tagged_at": "2023-02-17T10:43:55Z"
    }
  ],
  "pagination": {
    "has_previous_page": false,
    "has_next_page": false,
    "start_cursor": "WzQzXQ==",
    "end_cursor": "WzQyXQ==",
    "per_page": 500
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

404 Response

{
  "errors": [
    "Not Found"
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns a paginated list of all tags for a subscriber Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
404 Not Found Returns a 404 when the provided id does not exist Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» tags [object] true none none
»» id integer true none none
»» name string true none none
»» added_at string false none none
»» tagged_at string false none none
» pagination object false none none
»» has_previous_page boolean true none none
»» has_next_page boolean true none none
»» start_cursor string true none none
»» end_cursor string true none none
»» per_page integer true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 404

Name Type Required Restrictions Description
» errors [string] true none none

Tags

Bulk create tags

Code samples

# You can also use wget
curl -X POST https://api.convertkit.com/v4/bulk/tags \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'

const inputBody = '{
  "tags": [
    {
      "name": "string"
    }
  ],
  "callback_url": null
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/bulk/tags',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.post 'https://api.convertkit.com/v4/bulk/tags',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.post('https://api.convertkit.com/v4/bulk/tags', headers = headers)

print(r.json())

POST /v4/bulk/tags

Please see the note about "Bulk and async processing" for more information.

Body parameter

{
  "tags": [
    {
      "name": "string"
    }
  ],
  "callback_url": null
}

Parameters

Name In Type Required Description
Authorization header string true none
body body object false none
» tags body [object] true none
»» name body string true none
» callback_url body any false none

Example responses

200 Response

{
  "tags": [
    {
      "id": 25,
      "name": "Attended Event",
      "created_at": "2023-02-17T11:43:55Z"
    },
    {
      "id": 26,
      "name": "Newsletter",
      "created_at": "2023-02-17T11:43:55Z"
    },
    {
      "id": 27,
      "name": "Re-engage",
      "created_at": "2023-02-17T11:43:55Z"
    }
  ],
  "failures": [
    {
      "tag": {
        "id": 24,
        "name": "Existing Tag",
        "created_at": "2023-02-17T11:43:55Z"
      },
      "errors": [
        "Name has already been taken"
      ]
    }
  ]
}

202 Response

{}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

413 Response

{
  "errors": [
    "This request exceeds your queued bulk requests limit. Please wait while we process your existing requests and try again later."
  ]
}

422 Response

{
  "errors": [
    "No tags included for processing"
  ]
}

Responses

Status Meaning Description Schema
200 OK Creates the tags synchronously when 100 or less tags are requested Inline
202 Accepted Creates or updates tags asynchronously when more than 100 tags are requested Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
413 Payload Too Large Returns a 413 when the size of the request would exceed the account's data limit for enqueued bulk requests Inline
422 Unprocessable Entity Returns a 422 when tags is empty or not an array Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» tags [object] true none none
»» id integer true none none
»» name string true none none
»» created_at string true none none
» failures [object] true none none
»» tag object true none none
»»» id integer true none none
»»» name string true none none
»»» created_at string true none none
»» errors [string] true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 413

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 422

Name Type Required Restrictions Description
» errors [string] true none none

Bulk tag subscribers

Code samples

# You can also use wget
curl -X POST https://api.convertkit.com/v4/bulk/tags/subscribers \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'

const inputBody = '{
  "taggings": [
    {
      "tag_id": 0,
      "subscriber_id": 0
    }
  ],
  "callback_url": null
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/bulk/tags/subscribers',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.post 'https://api.convertkit.com/v4/bulk/tags/subscribers',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.post('https://api.convertkit.com/v4/bulk/tags/subscribers', headers = headers)

print(r.json())

POST /v4/bulk/tags/subscribers

Body parameter

{
  "taggings": [
    {
      "tag_id": 0,
      "subscriber_id": 0
    }
  ],
  "callback_url": null
}

Parameters

Name In Type Required Description
Authorization header string true none
body body object false none
» taggings body [object] true none
»» tag_id body integer true none
»» subscriber_id body integer true none
» callback_url body any false none

Example responses

200 Response

{
  "subscribers": [
    {
      "id": 273,
      "first_name": "Sub",
      "email_address": "sub@example.com",
      "created_at": "2023-02-17T11:43:55Z",
      "tagged_at": "2023-02-17T11:43:55Z"
    },
    {
      "id": 273,
      "first_name": "Sub",
      "email_address": "sub@example.com",
      "created_at": "2023-02-17T11:43:55Z",
      "tagged_at": "2023-02-17T11:43:55Z"
    }
  ],
  "failures": []
}

202 Response

{}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

413 Response

{
  "errors": [
    "This request exceeds your queued bulk requests limit. Please wait while we process your existing requests and try again later."
  ]
}

422 Response

{
  "errors": [
    "No taggings included for processing"
  ]
}

Responses

Status Meaning Description Schema
200 OK Creates the taggings synchronously when 100 or less tags/subscribers are requested Inline
202 Accepted Creates or updates taggings asynchronously when more than 100 custom fields are requested Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
413 Payload Too Large Returns a 413 when the size of the request would exceed the account's data limit for enqueued bulk requests Inline
422 Unprocessable Entity Returns a 422 when taggings is empty or not an array Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» subscribers [object] true none none
»» id integer true none none
»» first_name string true none none
»» email_address string true none none
»» created_at string true none none
»» tagged_at string true none none
» failures [any] true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 413

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 422

Name Type Required Restrictions Description
» errors [string] true none none

List tags

Code samples

# You can also use wget
curl -X GET https://api.convertkit.com/v4/tags \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/tags',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.get 'https://api.convertkit.com/v4/tags',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.get('https://api.convertkit.com/v4/tags', headers = headers)

print(r.json())

GET /v4/tags

Parameters

Name In Type Required Description
Authorization header string true none
after query any false To fetch next page of results, use ?after=<end_cursor>
before query any false To fetch previous page of results, use ?before=<start_cursor>
include_total_count query string false To include the total count of records in the response, use true. For large collections, expect a slightly slower response.
per_page query any false Number of results per page. Default 500, maximum 1000.

Example responses

200 Response

{
  "tags": [
    {
      "id": 5,
      "name": "Tag B",
      "created_at": "2023-02-17T11:43:55Z"
    },
    {
      "id": 4,
      "name": "Tag A",
      "created_at": "2023-02-17T11:43:55Z"
    }
  ],
  "pagination": {
    "has_previous_page": false,
    "has_next_page": false,
    "start_cursor": "WzVd",
    "end_cursor": "WzRd",
    "per_page": 500
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns a paginated list of all tags for your account Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» tags [object] true none none
»» id integer true none none
»» name string true none none
»» created_at string true none none
» pagination object true none none
»» has_previous_page boolean true none none
»» has_next_page boolean true none none
»» start_cursor string true none none
»» end_cursor string true none none
»» per_page integer true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Create a tag

Code samples

# You can also use wget
curl -X POST https://api.convertkit.com/v4/tags \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'

const inputBody = '{
  "name": "string"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/tags',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.post 'https://api.convertkit.com/v4/tags',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.post('https://api.convertkit.com/v4/tags', headers = headers)

print(r.json())

POST /v4/tags

Body parameter

{
  "name": "string"
}

Parameters

Name In Type Required Description
Authorization header string true none
body body object false none
» name body string true none

Example responses

201 Response

{
  "tag": {
    "id": 9,
    "name": "Completed",
    "created_at": "2023-02-17T11:43:55Z"
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

422 Response

{
  "errors": [
    "Name has already been taken"
  ]
}

Responses

Status Meaning Description Schema
201 Created Creates the tag Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
422 Unprocessable Entity Returns a 422 with an error message when the tag already exists Inline

Response Schema

Status Code 201

Name Type Required Restrictions Description
» tag object true none none
»» id integer true none none
»» name string true none none
»» created_at string true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 422

Name Type Required Restrictions Description
» errors [string] true none none

Remove tag from subscriber by email address

Code samples

# You can also use wget
curl -X DELETE https://api.convertkit.com/v4/tags/{tag_id}/subscribers \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -H 'Accept: ' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'

const inputBody = '{
  "email_address": "string"
}';
const headers = {
  'Content-Type':'application/x-www-form-urlencoded',
  'Accept':'',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/tags/{tag_id}/subscribers',
{
  method: 'DELETE',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/x-www-form-urlencoded',
  'Accept' => '',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.delete 'https://api.convertkit.com/v4/tags/{tag_id}/subscribers',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/x-www-form-urlencoded',
  'Accept': '',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.delete('https://api.convertkit.com/v4/tags/{tag_id}/subscribers', headers = headers)

print(r.json())

DELETE /v4/tags/{tag_id}/subscribers

Body parameter

email_address: string

Parameters

Name In Type Required Description
Authorization header string true none
tag_id path integer true none
body body object false none
» email_address body string true none

Example responses

204 Response

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

404 Response

{
  "errors": [
    "Not Found"
  ]
}

422 Response

{
  "errors": [
    "Either subscriber id or email address is required to remove tag from subscriber"
  ]
}

Responses

Status Meaning Description Schema
204 No Content Removes the tag from the subscriber string
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
404 Not Found Returns a 404 when the provided id does not exist Inline
422 Unprocessable Entity Returns a 422 with an error message when missing email address Inline

Response Schema

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 404

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 422

Name Type Required Restrictions Description
» errors [string] true none none

List subscribers for a tag

Code samples

# You can also use wget
curl -X GET https://api.convertkit.com/v4/tags/{tag_id}/subscribers \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/tags/{tag_id}/subscribers',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.get 'https://api.convertkit.com/v4/tags/{tag_id}/subscribers',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.get('https://api.convertkit.com/v4/tags/{tag_id}/subscribers', headers = headers)

print(r.json())

GET /v4/tags/{tag_id}/subscribers

Parameters

Name In Type Required Description
Authorization header string true none
after query any false To fetch next page of results, use ?after=<end_cursor>
before query any false To fetch previous page of results, use ?before=<start_cursor>
created_after query any false Filter subscribers who have been created after this date (format yyyy-mm-dd)
created_before query any false Filter subscribers who have been created before this date (format yyyy-mm-dd)
include_total_count query string false To include the total count of records in the response, use true. For large collections, expect a slightly slower response.
per_page query any false Number of results per page. Default 500, maximum 1000.
status query string false Filter subscribers who have this status (active, inactive, bounced, complained, cancelled or all). Defaults to active.
tag_id path integer true none
tagged_after query any false Filter subscribers who have been tagged after this date (format yyyy-mm-dd)
tagged_before query any false Filter subscribers who have been tagged before this date (format yyyy-mm-dd)

Example responses

200 Response

{
  "subscribers": [
    {
      "id": 550,
      "first_name": null,
      "email_address": "subscriber299@convertkit.dev",
      "state": "active",
      "created_at": "2023-02-17T11:43:55Z",
      "tagged_at": "2023-02-17T11:43:55Z",
      "fields": {
        "category": "One"
      }
    },
    {
      "id": 549,
      "first_name": null,
      "email_address": "subscriber298@convertkit.dev",
      "state": "active",
      "created_at": "2023-02-17T11:43:55Z",
      "tagged_at": "2023-02-17T11:43:55Z",
      "fields": {
        "category": null
      }
    },
    {
      "id": 548,
      "first_name": null,
      "email_address": "subscriber297@convertkit.dev",
      "state": "active",
      "created_at": "2023-02-17T11:43:55Z",
      "tagged_at": "2023-02-17T11:43:55Z",
      "fields": {
        "category": null
      }
    }
  ],
  "pagination": {
    "has_previous_page": false,
    "has_next_page": false,
    "start_cursor": "WzU1MF0=",
    "end_cursor": "WzU0OF0=",
    "per_page": 500
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

404 Response

{
  "errors": [
    "Not Found"
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns a paginated list of subscribers for the specified tag Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
404 Not Found Returns a 404 when the provided id does not exist Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» subscribers [object] true none none
»» id integer true none none
»» first_name any true none none
»» email_address string true none none
»» state string true none none
»» created_at string true none none
»» tagged_at string true none none
»» fields object true none none
»»» category string true none none
» pagination object true none none
»» has_previous_page boolean true none none
»» has_next_page boolean true none none
»» start_cursor string¦null true none none
»» end_cursor string¦null true none none
»» per_page integer true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 404

Name Type Required Restrictions Description
» errors [string] true none none

Tag a subscriber by email address

Code samples

# You can also use wget
curl -X POST https://api.convertkit.com/v4/tags/{tag_id}/subscribers \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'

const inputBody = '{
  "email_address": "string"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/tags/{tag_id}/subscribers',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.post 'https://api.convertkit.com/v4/tags/{tag_id}/subscribers',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.post('https://api.convertkit.com/v4/tags/{tag_id}/subscribers', headers = headers)

print(r.json())

POST /v4/tags/{tag_id}/subscribers

Body parameter

{
  "email_address": "string"
}

Parameters

Name In Type Required Description
Authorization header string true none
tag_id path integer true none
body body object false none
» email_address body string true none

Example responses

200 Response

{
  "subscriber": {
    "id": 628,
    "first_name": "Alice",
    "email_address": "alice@convertkit.dev",
    "state": "active",
    "created_at": "2023-02-17T11:43:55Z",
    "tagged_at": "2023-02-17T11:43:55Z",
    "fields": {}
  }
}

201 Response

{
  "subscriber": {
    "id": 629,
    "first_name": "Alice",
    "email_address": "alice@convertkit.dev",
    "state": "active",
    "created_at": "2023-02-17T11:43:55Z",
    "tagged_at": "2023-02-17T11:43:55Z",
    "fields": {}
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

404 Response

{
  "errors": [
    "Not Found"
  ]
}

422 Response

{
  "errors": [
    "Either subscriber id or email address is required to tag subscriber"
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns a 200 when the subscriber already has the tag Inline
201 Created Tags the subscriber Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
404 Not Found Returns a 404 when the provided id does not exist Inline
422 Unprocessable Entity Returns a 422 with an error message when missing email address Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» subscriber object true none none
»» id integer true none none
»» first_name string true none none
»» email_address string true none none
»» state string true none none
»» created_at string true none none
»» tagged_at string true none none
»» fields object true none none

Status Code 201

Name Type Required Restrictions Description
» subscriber object true none none
»» id integer true none none
»» first_name string true none none
»» email_address string true none none
»» state string true none none
»» created_at string true none none
»» tagged_at string true none none
»» fields object true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 404

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 422

Name Type Required Restrictions Description
» errors [string] true none none

Remove tag from subscriber

Code samples

# You can also use wget
curl -X DELETE https://api.convertkit.com/v4/tags/{tag_id}/subscribers/{id} \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -H 'Accept: ' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'

const inputBody = '{}';
const headers = {
  'Content-Type':'application/x-www-form-urlencoded',
  'Accept':'',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/tags/{tag_id}/subscribers/{id}',
{
  method: 'DELETE',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/x-www-form-urlencoded',
  'Accept' => '',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.delete 'https://api.convertkit.com/v4/tags/{tag_id}/subscribers/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/x-www-form-urlencoded',
  'Accept': '',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.delete('https://api.convertkit.com/v4/tags/{tag_id}/subscribers/{id}', headers = headers)

print(r.json())

DELETE /v4/tags/{tag_id}/subscribers/{id}

Body parameter

{}

Parameters

Name In Type Required Description
Authorization header string true none
id path integer true none
tag_id path integer true none
body body object false none

Example responses

204 Response

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

404 Response

{
  "errors": [
    "Not Found"
  ]
}

Responses

Status Meaning Description Schema
204 No Content Removes the tag from the subscriber string
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
404 Not Found Returns a 404 when the provided id does not exist Inline

Response Schema

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 404

Name Type Required Restrictions Description
» errors [string] true none none

Tag a subscriber

Code samples

# You can also use wget
curl -X POST https://api.convertkit.com/v4/tags/{tag_id}/subscribers/{id} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'

const inputBody = '{}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/tags/{tag_id}/subscribers/{id}',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.post 'https://api.convertkit.com/v4/tags/{tag_id}/subscribers/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.post('https://api.convertkit.com/v4/tags/{tag_id}/subscribers/{id}', headers = headers)

print(r.json())

POST /v4/tags/{tag_id}/subscribers/{id}

Body parameter

{}

Parameters

Name In Type Required Description
Authorization header string true none
id path integer true none
tag_id path integer true none
body body object false none

Example responses

200 Response

{
  "subscriber": {
    "id": 618,
    "first_name": "Alice",
    "email_address": "alice@convertkit.dev",
    "state": "active",
    "created_at": "2023-02-17T11:43:55Z",
    "tagged_at": "2023-02-17T11:43:55Z",
    "fields": {}
  }
}

201 Response

{
  "subscriber": {
    "id": 619,
    "first_name": "Alice",
    "email_address": "alice@convertkit.dev",
    "state": "active",
    "created_at": "2023-02-17T11:43:55Z",
    "tagged_at": "2023-02-17T11:43:55Z",
    "fields": {}
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

404 Response

{
  "errors": [
    "Not Found"
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns a 200 when the subscriber already has the tag Inline
201 Created Tags the subscriber Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
404 Not Found Returns a 404 when the provided id does not exist Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» subscriber object true none none
»» id integer true none none
»» first_name string true none none
»» email_address string true none none
»» state string true none none
»» created_at string true none none
»» tagged_at string true none none
»» fields object true none none

Status Code 201

Name Type Required Restrictions Description
» subscriber object true none none
»» id integer true none none
»» first_name string true none none
»» email_address string true none none
»» state string true none none
»» created_at string true none none
»» tagged_at string true none none
»» fields object true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 404

Name Type Required Restrictions Description
» errors [string] true none none

Email Templates

List email templates

Code samples

# You can also use wget
curl -X GET https://api.convertkit.com/v4/email_templates \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/email_templates',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.get 'https://api.convertkit.com/v4/email_templates',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.get('https://api.convertkit.com/v4/email_templates', headers = headers)

print(r.json())

GET /v4/email_templates

Parameters

Name In Type Required Description
Authorization header string true none
after query any false none
before query any false none
include_total_count query string false To include the total count of records in the response, use true. For large collections, expect a slightly slower response.
per_page query any false none

Example responses

200 Response

{
  "pagination": {
    "has_previous_page": false,
    "has_next_page": false,
    "start_cursor": "Wzhd",
    "end_cursor": "WzFd",
    "per_page": 500
  },
  "email_templates": [
    {
      "id": 8,
      "name": "Custom HTML Template",
      "is_default": false,
      "category": "HTML"
    },
    {
      "id": 7,
      "name": "Story",
      "is_default": false,
      "category": "Starting point"
    },
    {
      "id": 6,
      "name": "Text Only",
      "is_default": true,
      "category": "HTML"
    },
    {
      "id": 4,
      "name": "Modern",
      "is_default": false,
      "category": "HTML"
    },
    {
      "id": 2,
      "name": "Classic",
      "is_default": false,
      "category": "HTML"
    },
    {
      "id": 1,
      "name": "Card",
      "is_default": false,
      "category": "HTML"
    }
  ]
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns a paginated list of all email templates for your account Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» pagination object true none none
»» has_previous_page boolean true none none
»» has_next_page boolean true none none
»» start_cursor string true none none
»» end_cursor string true none none
»» per_page integer true none none
» email_templates [object] false none none
»» id integer true none none
»» name string true none none
»» is_default boolean true none none
»» category string true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Forms

List forms

Code samples

# You can also use wget
curl -X GET https://api.convertkit.com/v4/forms \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/forms',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.get 'https://api.convertkit.com/v4/forms',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.get('https://api.convertkit.com/v4/forms', headers = headers)

print(r.json())

GET /v4/forms

Parameters

Name In Type Required Description
Authorization header string true none
after query any false To fetch next page of results, use ?after=<end_cursor>
before query any false To fetch previous page of results, use ?before=<start_cursor>
include_total_count query string false To include the total count of records in the response, use true. For large collections, expect a slightly slower response.
per_page query any false Number of results per page. Default 500, maximum 1000.
status query any false Filter forms that have this status (active, archived, trashed, or all). Defaults to active.
type query any false Filter forms and landing pages by type. Use embed for embedded forms. Use hosted for landing pages.

Example responses

200 Response

{
  "forms": [
    {
      "id": 31,
      "name": "Sign up",
      "created_at": "2023-02-17T11:43:55Z",
      "type": "embed",
      "format": null,
      "embed_js": "https://ck-greetings.ck.page/f049e3d9ab/index.js",
      "embed_url": "https://ck-greetings.ck.page/f049e3d9ab",
      "archived": false,
      "uid": "f049e3d9ab"
    },
    {
      "id": 30,
      "name": "Lead gen",
      "created_at": "2023-02-17T11:43:55Z",
      "type": "hosted",
      "format": null,
      "embed_js": "https://ck-greetings.ck.page/ae7c1adaa1/index.js",
      "embed_url": "https://ck-greetings.ck.page/ae7c1adaa1",
      "archived": false,
      "uid": "ae7c1adaa1"
    }
  ],
  "pagination": {
    "has_previous_page": false,
    "has_next_page": false,
    "start_cursor": "WzMxXQ==",
    "end_cursor": "WzMwXQ==",
    "per_page": 500
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns a paginated list of all forms and landing pages (embedded and hosted) for your account (including active and archived) Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» forms [object] true none none
»» id integer true none none
»» name string true none none
»» created_at string true none none
»» type string true none none
»» format any true none none
»» embed_js string true none none
»» embed_url string true none none
»» archived boolean true none none
»» uid string true none none
» pagination object true none none
»» has_previous_page boolean true none none
»» has_next_page boolean true none none
»» start_cursor string¦null true none none
»» end_cursor string¦null true none none
»» per_page integer true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

List subscribers for a form

Code samples

# You can also use wget
curl -X GET https://api.convertkit.com/v4/forms/{form_id}/subscribers \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/forms/{form_id}/subscribers',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.get 'https://api.convertkit.com/v4/forms/{form_id}/subscribers',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.get('https://api.convertkit.com/v4/forms/{form_id}/subscribers', headers = headers)

print(r.json())

GET /v4/forms/{form_id}/subscribers

Parameters

Name In Type Required Description
Authorization header string true none
added_after query any false Filter subscribers who have been added to the form after this date (format yyyy-mm-dd)
added_before query any false Filter subscribers who have been added to the form before this date (format yyyy-mm-dd)
after query any false none
before query any false none
created_after query any false Filter subscribers who have been created after this date (format yyyy-mm-dd)
created_before query any false Filter subscribers who have been created before this date (format yyyy-mm-dd)
form_id path integer true none
include_total_count query string false To include the total count of records in the response, use true. For large collections, expect a slightly slower response.
per_page query any false none
status query string false Filter subscribers who have this status (active, inactive, bounced, complained, cancelled or all). Defaults to active.

Example responses

200 Response

{
  "subscribers": [
    {
      "id": 281,
      "first_name": null,
      "email_address": "subscriber109@convertkit.dev",
      "state": "active",
      "created_at": "2023-02-17T11:43:55Z",
      "added_at": "2023-02-17T11:43:55Z",
      "fields": {
        "category": "One"
      }
    },
    {
      "id": 280,
      "first_name": null,
      "email_address": "subscriber108@convertkit.dev",
      "state": "active",
      "created_at": "2023-02-17T11:43:55Z",
      "added_at": "2023-02-17T11:43:55Z",
      "fields": {
        "category": null
      }
    },
    {
      "id": 279,
      "first_name": null,
      "email_address": "subscriber107@convertkit.dev",
      "state": "active",
      "created_at": "2023-02-17T11:43:55Z",
      "added_at": "2023-02-17T11:43:55Z",
      "fields": {
        "category": null
      }
    }
  ],
  "pagination": {
    "has_previous_page": false,
    "has_next_page": false,
    "start_cursor": "WzI4MV0=",
    "end_cursor": "WzI3OV0=",
    "per_page": 500
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

404 Response

{
  "errors": [
    "Not Found"
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns a paginated list of subscribers for the specified form Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
404 Not Found Returns a 404 when the provided id does not exist Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» subscribers [object] true none none
»» id integer true none none
»» first_name any true none none
»» email_address string true none none
»» state string true none none
»» created_at string true none none
»» added_at string true none none
»» fields object true none none
»»» category string true none none
» pagination object true none none
»» has_previous_page boolean true none none
»» has_next_page boolean true none none
»» start_cursor string true none none
»» end_cursor string true none none
»» per_page integer true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 404

Name Type Required Restrictions Description
» errors [string] true none none

Add subscriber to form by email address

Code samples

# You can also use wget
curl -X POST https://api.convertkit.com/v4/forms/{form_id}/subscribers \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'

const inputBody = '{
  "email_address": "string"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/forms/{form_id}/subscribers',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.post 'https://api.convertkit.com/v4/forms/{form_id}/subscribers',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.post('https://api.convertkit.com/v4/forms/{form_id}/subscribers', headers = headers)

print(r.json())

POST /v4/forms/{form_id}/subscribers

Body parameter

{
  "email_address": "string"
}

Parameters

Name In Type Required Description
Authorization header string true none
form_id path integer true none
body body object false none
» email_address body string true none

Example responses

200 Response

{
  "subscriber": {
    "id": 359,
    "first_name": "Alice",
    "email_address": "alice@convertkit.dev",
    "state": "active",
    "created_at": "2023-02-17T11:43:55Z",
    "added_at": "2023-02-17T11:43:55Z",
    "fields": {}
  }
}

201 Response

{
  "subscriber": {
    "id": 360,
    "first_name": "Alice",
    "email_address": "alice@convertkit.dev",
    "state": "active",
    "created_at": "2023-02-17T11:43:55Z",
    "added_at": "2023-02-17T11:43:55Z",
    "fields": {}
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

404 Response

{
  "errors": [
    "Not Found"
  ]
}

422 Response

{
  "errors": [
    "Either subscriber id or email address is required to add subscriber to form"
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns a 200 when the subscriber has already been added to the form Inline
201 Created Adds the subscriber to the form Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
404 Not Found Returns a 404 when the provided id does not exist Inline
422 Unprocessable Entity Returns a 422 with an error message when missing email address Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» subscriber object true none none
»» id integer true none none
»» first_name string true none none
»» email_address string true none none
»» state string true none none
»» created_at string true none none
»» added_at string true none none
»» fields object true none none

Status Code 201

Name Type Required Restrictions Description
» subscriber object true none none
»» id integer true none none
»» first_name string true none none
»» email_address string true none none
»» state string true none none
»» created_at string true none none
»» added_at string true none none
»» fields object true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 404

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 422

Name Type Required Restrictions Description
» errors [string] true none none

Add subscriber to form

Code samples

# You can also use wget
curl -X POST https://api.convertkit.com/v4/forms/{form_id}/subscribers/{id} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'

const inputBody = '{}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/forms/{form_id}/subscribers/{id}',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.post 'https://api.convertkit.com/v4/forms/{form_id}/subscribers/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.post('https://api.convertkit.com/v4/forms/{form_id}/subscribers/{id}', headers = headers)

print(r.json())

POST /v4/forms/{form_id}/subscribers/{id}

Body parameter

{}

Parameters

Name In Type Required Description
Authorization header string true none
form_id path integer true none
id path integer true none
body body object false none

Example responses

200 Response

{
  "subscriber": {
    "id": 349,
    "first_name": "Alice",
    "email_address": "alice@convertkit.dev",
    "state": "active",
    "created_at": "2023-02-17T11:43:55Z",
    "added_at": "2023-02-17T11:43:55Z",
    "fields": {}
  }
}

201 Response

{
  "subscriber": {
    "id": 350,
    "first_name": "Alice",
    "email_address": "alice@convertkit.dev",
    "state": "active",
    "created_at": "2023-02-17T11:43:55Z",
    "added_at": "2023-02-17T11:43:55Z",
    "fields": {}
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

404 Response

{
  "errors": [
    "Not Found"
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns a 200 when the subscriber has already been added to the form Inline
201 Created Adds the subscriber to the form Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
404 Not Found Returns a 404 when the provided id does not exist Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» subscriber object true none none
»» id integer true none none
»» first_name string true none none
»» email_address string true none none
»» state string true none none
»» created_at string true none none
»» added_at string true none none
»» fields object true none none

Status Code 201

Name Type Required Restrictions Description
» subscriber object true none none
»» id integer true none none
»» first_name string true none none
»» email_address string true none none
»» state string true none none
»» created_at string true none none
»» added_at string true none none
»» fields object true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 404

Name Type Required Restrictions Description
» errors [string] true none none

Purchases

List purchases

Code samples

# You can also use wget
curl -X GET https://api.convertkit.com/v4/purchases \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/purchases',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.get 'https://api.convertkit.com/v4/purchases',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.get('https://api.convertkit.com/v4/purchases', headers = headers)

print(r.json())

GET /v4/purchases

Parameters

Name In Type Required Description
Authorization header string true none
after query any false To fetch next page of results, use ?after=<end_cursor>
before query any false To fetch previous page of results, use ?before=<start_cursor>
include_total_count query string false To include the total count of records in the response, use true. For large collections, expect a slightly slower response.
per_page query any false Number of results per page. Default 500, maximum 1000.

Example responses

200 Response

{
  "purchases": [
    {
      "id": 3,
      "transaction_id": "512-41-4101",
      "status": "paid",
      "email_address": "pru.magoo@convertkit.dev",
      "currency": "USD",
      "transaction_time": "2023-02-17T11:43:55Z",
      "subtotal": 5,
      "discount": 0,
      "tax": 0,
      "total": 5,
      "products": [
        {
          "quantity": 1,
          "lid": "000-13-0000",
          "unit_price": 0.05,
          "sku": null,
          "name": "Tip",
          "pid": "111-75-7524"
        }
      ]
    },
    {
      "id": 2,
      "transaction_id": "323-79-5320",
      "status": "paid",
      "email_address": "pru.magoo@convertkit.dev",
      "currency": "USD",
      "transaction_time": "2023-02-17T11:43:55Z",
      "subtotal": 10,
      "discount": 0,
      "tax": 1.05,
      "total": 11.05,
      "products": [
        {
          "quantity": 1,
          "lid": "000-12-0000",
          "unit_price": 0.1,
          "sku": null,
          "name": "Monthly Game Review",
          "pid": "000-11-0000"
        }
      ]
    },
    {
      "id": 1,
      "transaction_id": "796-92-4892",
      "status": "paid",
      "email_address": "pru.magoo@convertkit.dev",
      "currency": "USD",
      "transaction_time": "2023-02-17T11:43:55Z",
      "subtotal": 78.66,
      "discount": 5,
      "tax": 7.87,
      "total": 81.53,
      "products": [
        {
          "quantity": 1,
          "lid": "811-75-7900",
          "unit_price": 23.22,
          "sku": null,
          "name": "Phantom Hourglass",
          "pid": "804-02-4430"
        },
        {
          "quantity": 1,
          "lid": "766-49-1241",
          "unit_price": 32.22,
          "sku": null,
          "name": "Twilight Princess",
          "pid": "833-51-1151"
        }
      ]
    }
  ],
  "pagination": {
    "has_previous_page": false,
    "has_next_page": false,
    "start_cursor": "WzNd",
    "end_cursor": "WzFd",
    "per_page": 500
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns a paginated list of all purchases for your account Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» purchases [object] true none none
»» id integer true none none
»» transaction_id string true none none
»» status string true none none
»» email_address string true none none
»» currency string true none none
»» transaction_time string true none none
»» subtotal number(float) true none none
»» discount number(float) true none none
»» tax number(float) true none none
»» total number(float) true none none
»» products [object] true none none
»»» quantity integer true none none
»»» lid string true none none
»»» unit_price number(float) true none none
»»» sku any true none none
»»» name string true none none
»»» pid string true none none
» pagination object true none none
»» has_previous_page boolean true none none
»» has_next_page boolean true none none
»» start_cursor string¦null true none none
»» end_cursor string¦null true none none
»» per_page integer true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Create a purchase

Code samples

# You can also use wget
curl -X POST https://api.convertkit.com/v4/purchases \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'

const inputBody = '{
  "purchase": {
    "email_address": "string",
    "first_name": "string",
    "transaction_id": "string",
    "status": "string",
    "subtotal": 0.1,
    "tax": 0.1,
    "shipping": 0,
    "discount": 0.1,
    "total": 0.1,
    "currency": "string",
    "transaction_time": "string",
    "products": [
      {
        "name": "string",
        "pid": "string",
        "lid": "string",
        "quantity": 0,
        "sku": "string",
        "unit_price": 0.1
      }
    ]
  }
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/purchases',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.post 'https://api.convertkit.com/v4/purchases',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.post('https://api.convertkit.com/v4/purchases', headers = headers)

print(r.json())

POST /v4/purchases

Body parameter

{
  "purchase": {
    "email_address": "string",
    "first_name": "string",
    "transaction_id": "string",
    "status": "string",
    "subtotal": 0.1,
    "tax": 0.1,
    "shipping": 0,
    "discount": 0.1,
    "total": 0.1,
    "currency": "string",
    "transaction_time": "string",
    "products": [
      {
        "name": "string",
        "pid": "string",
        "lid": "string",
        "quantity": 0,
        "sku": "string",
        "unit_price": 0.1
      }
    ]
  }
}

Parameters

Name In Type Required Description
Authorization header string true none
body body object false none
» purchase body object true none
»» email_address body string true The subscriber that the purchase belongs to
»» first_name body string¦null false The first name of the subscriber
»» transaction_id body string true A unique ID for the purchase
»» status body string¦null false We currently support a status of paid
»» subtotal body number(float)¦null false none
»» tax body number(float)¦null false none
»» shipping body integer¦null false none
»» discount body number(float)¦null false none
»» total body number(float)¦null false none
»» currency body string true 3 letter currency code (e.g. USD)
»» transaction_time body string¦null false none
»» products body [object] true Array of purchased products
»»» name body string true Product name
»»» pid body string true This is your identifier for a product. Each product provided in the products array must have a unique pid. Variants of the same product should have the same pid.
»»» lid body string true Each product should have a unique lid (i.e., line item identifier) for this purchase.
»»» quantity body integer true Product quantity
»»» sku body string¦null false Product sku
»»» unit_price body number(float) true Product price

Example responses

201 Response

{
  "purchase": {
    "id": 17,
    "transaction_id": "796-92-4892",
    "status": "paid",
    "email_address": "pru.magoo@convertkit.dev",
    "currency": "USD",
    "transaction_time": "2023-02-17T11:43:55Z",
    "subtotal": 78.66,
    "discount": 5,
    "tax": 7.87,
    "total": 81.53,
    "products": [
      {
        "quantity": 1,
        "lid": "811-75-7900",
        "unit_price": 23.22,
        "sku": "SM21-SH-M02-RD-S-001",
        "name": "Phantom Hourglass",
        "pid": "804-02-4430"
      },
      {
        "quantity": 1,
        "lid": "766-49-1241",
        "unit_price": 32.22,
        "sku": "WT21-JK-M03-BK-L-012",
        "name": "Twilight Princess",
        "pid": "833-51-1151"
      },
      {
        "quantity": 1,
        "lid": "563-95-8878",
        "unit_price": 23.22,
        "sku": "FL21-TS-M01-BL-M-020",
        "name": "Four Swords",
        "pid": "217-99-4325"
      }
    ]
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

422 Response

{
  "errors": [
    "Transaction cannot be blank"
  ]
}

Responses

Status Meaning Description Schema
201 Created Creates a purchase for the provided subscriber and returns its details. It also creates products if they don't exist. Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
422 Unprocessable Entity Returns a 422 when one or more of the parameters are invalid Inline

Response Schema

Status Code 201

Name Type Required Restrictions Description
» purchase object true none none
»» id integer true none none
»» transaction_id string true none none
»» status string true none none
»» email_address string true none none
»» currency string true none none
»» transaction_time string true none none
»» subtotal number(float) true none none
»» discount number(float) true none none
»» tax number(float) true none none
»» total number(float) true none none
»» products [object] true none none
»»» quantity integer true none none
»»» lid string true none none
»»» unit_price number(float) true none none
»»» sku string¦null true none none
»»» name string true none none
»»» pid string true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 422

Name Type Required Restrictions Description
» errors [string] true none none

Get a purchase

Code samples

# You can also use wget
curl -X GET https://api.convertkit.com/v4/purchases/{id} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/purchases/{id}',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.get 'https://api.convertkit.com/v4/purchases/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.get('https://api.convertkit.com/v4/purchases/{id}', headers = headers)

print(r.json())

GET /v4/purchases/{id}

Parameters

Name In Type Required Description
Authorization header string true none
id path integer true none

Example responses

200 Response

{
  "purchase": {
    "id": 11,
    "transaction_id": "796-92-4892",
    "status": "paid",
    "email_address": "pru.magoo@convertkit.dev",
    "currency": "USD",
    "transaction_time": "2023-02-17T11:43:55Z",
    "subtotal": 78.66,
    "discount": 5,
    "tax": 7.87,
    "total": 81.53,
    "products": [
      {
        "quantity": 1,
        "lid": "811-75-7900",
        "unit_price": 23.22,
        "sku": null,
        "name": "Phantom Hourglass",
        "pid": "804-02-4430"
      },
      {
        "quantity": 1,
        "lid": "766-49-1241",
        "unit_price": 32.22,
        "sku": null,
        "name": "Twilight Princess",
        "pid": "833-51-1151"
      }
    ]
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

404 Response

{
  "errors": [
    "Not Found"
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns the purchase details Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
404 Not Found Returns a 404 when the provided id does not exist Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» purchase object true none none
»» id integer true none none
»» transaction_id string true none none
»» status string true none none
»» email_address string true none none
»» currency string true none none
»» transaction_time string true none none
»» subtotal number(float) true none none
»» discount number(float) true none none
»» tax number(float) true none none
»» total number(float) true none none
»» products [object] true none none
»»» quantity integer true none none
»»» lid string true none none
»»» unit_price number(float) true none none
»»» sku any true none none
»»» name string true none none
»»» pid string true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 404

Name Type Required Restrictions Description
» errors [string] true none none

Segments

List segments

Code samples

# You can also use wget
curl -X GET https://api.convertkit.com/v4/segments \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/segments',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.get 'https://api.convertkit.com/v4/segments',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.get('https://api.convertkit.com/v4/segments', headers = headers)

print(r.json())

GET /v4/segments

Parameters

Name In Type Required Description
Authorization header string true none
after query any false none
before query any false none
include_total_count query string false To include the total count of records in the response, use true. For large collections, expect a slightly slower response.
per_page query any false none

Example responses

200 Response

{
  "segments": [
    {
      "id": 38,
      "name": "Segment B",
      "created_at": "2023-02-17T11:43:55Z"
    },
    {
      "id": 37,
      "name": "Segment A",
      "created_at": "2023-02-17T11:43:55Z"
    }
  ],
  "pagination": {
    "has_previous_page": false,
    "has_next_page": false,
    "start_cursor": "WzM4XQ==",
    "end_cursor": "WzM3XQ==",
    "per_page": 500
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns a paginated list of all segments for your account Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» segments [object] true none none
»» id integer true none none
»» name string true none none
»» created_at string true none none
» pagination object true none none
»» has_previous_page boolean true none none
»» has_next_page boolean true none none
»» start_cursor string true none none
»» end_cursor string true none none
»» per_page integer true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Sequences

List sequences

Code samples

# You can also use wget
curl -X GET https://api.convertkit.com/v4/sequences \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/sequences',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.get 'https://api.convertkit.com/v4/sequences',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.get('https://api.convertkit.com/v4/sequences', headers = headers)

print(r.json())

GET /v4/sequences

Parameters

Name In Type Required Description
Authorization header string true none
after query any false To fetch next page of results, use ?after=<end_cursor>
before query any false To fetch previous page of results, use ?before=<start_cursor>
include_total_count query string false To include the total count of records in the response, use true. For large collections, expect a slightly slower response.
per_page query any false Number of results per page. Default 500, maximum 1000.

Example responses

200 Response

{
  "sequences": [
    {
      "id": 1,
      "name": "Evergreen sequence",
      "hold": false,
      "repeat": false,
      "created_at": "2023-02-17T11:43:55Z"
    }
  ],
  "pagination": {
    "has_previous_page": false,
    "has_next_page": false,
    "start_cursor": "WzFd",
    "end_cursor": "WzFd",
    "per_page": 500
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns a paginated list of all sequences for your account Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» sequences [object] true none none
»» id integer true none none
»» name string true none none
»» hold boolean true none none
»» repeat boolean true none none
»» created_at string true none none
» pagination object true none none
»» has_previous_page boolean true none none
»» has_next_page boolean true none none
»» start_cursor string¦null true none none
»» end_cursor string¦null true none none
»» per_page integer true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

List subscribers for a sequence

Code samples

# You can also use wget
curl -X GET https://api.convertkit.com/v4/sequences/{sequence_id}/subscribers \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/sequences/{sequence_id}/subscribers',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.get 'https://api.convertkit.com/v4/sequences/{sequence_id}/subscribers',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.get('https://api.convertkit.com/v4/sequences/{sequence_id}/subscribers', headers = headers)

print(r.json())

GET /v4/sequences/{sequence_id}/subscribers

Parameters

Name In Type Required Description
Authorization header string true none
added_after query any false Filter subscribers who have been added to the sequence after this date (format yyyy-mm-dd)
added_before query any false Filter subscribers who have been added to the sequence before this date (format yyyy-mm-dd)
after query any false none
before query any false none
created_after query any false Filter subscribers who have been created after this date (format yyyy-mm-dd)
created_before query any false Filter subscribers who have been created before this date (format yyyy-mm-dd)
include_total_count query string false To include the total count of records in the response, use true. For large collections, expect a slightly slower response.
per_page query any false none
sequence_id path integer true none
status query string false Filter subscribers who have this status (active, inactive, bounced, complained, cancelled or all). Defaults to active.

Example responses

200 Response

{
  "subscribers": [
    {
      "id": 451,
      "first_name": null,
      "email_address": "subscriber235@convertkit.dev",
      "state": "active",
      "created_at": "2023-02-17T11:43:55Z",
      "added_at": "2023-02-17T11:43:55Z",
      "fields": {
        "category": "One"
      }
    },
    {
      "id": 450,
      "first_name": null,
      "email_address": "subscriber234@convertkit.dev",
      "state": "active",
      "created_at": "2023-02-17T11:43:55Z",
      "added_at": "2023-02-17T11:43:55Z",
      "fields": {
        "category": null
      }
    },
    {
      "id": 449,
      "first_name": null,
      "email_address": "subscriber233@convertkit.dev",
      "state": "active",
      "created_at": "2023-02-17T11:43:55Z",
      "added_at": "2023-02-17T11:43:55Z",
      "fields": {
        "category": null
      }
    }
  ],
  "pagination": {
    "has_previous_page": false,
    "has_next_page": false,
    "start_cursor": "WzQ1MV0=",
    "end_cursor": "WzQ0OV0=",
    "per_page": 500
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

404 Response

{
  "errors": [
    "Not Found"
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns a paginated list of subscribers for the specified sequence Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
404 Not Found Returns a 404 when the provided id does not exist Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» subscribers [object] true none none
»» id integer true none none
»» first_name any true none none
»» email_address string true none none
»» state string true none none
»» created_at string true none none
»» added_at string true none none
»» fields object true none none
»»» category string true none none
» pagination object true none none
»» has_previous_page boolean true none none
»» has_next_page boolean true none none
»» start_cursor string true none none
»» end_cursor string true none none
»» per_page integer true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 404

Name Type Required Restrictions Description
» errors [string] true none none

Add subscriber to sequence by email address

Code samples

# You can also use wget
curl -X POST https://api.convertkit.com/v4/sequences/{sequence_id}/subscribers \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'

const inputBody = '{
  "email_address": "string"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/sequences/{sequence_id}/subscribers',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.post 'https://api.convertkit.com/v4/sequences/{sequence_id}/subscribers',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.post('https://api.convertkit.com/v4/sequences/{sequence_id}/subscribers', headers = headers)

print(r.json())

POST /v4/sequences/{sequence_id}/subscribers

Body parameter

{
  "email_address": "string"
}

Parameters

Name In Type Required Description
Authorization header string true none
sequence_id path integer true none
body body object false none
» email_address body string true none

Example responses

200 Response

{
  "subscriber": {
    "id": 529,
    "first_name": "Alice",
    "email_address": "alice@convertkit.dev",
    "state": "active",
    "created_at": "2023-02-17T11:43:55Z",
    "added_at": "2023-02-17T11:43:55Z",
    "fields": {}
  }
}

201 Response

{
  "subscriber": {
    "id": 530,
    "first_name": "Alice",
    "email_address": "alice@convertkit.dev",
    "state": "active",
    "created_at": "2023-02-17T11:43:55Z",
    "added_at": "2023-02-17T11:43:55Z",
    "fields": {}
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

404 Response

{
  "errors": [
    "Not Found"
  ]
}

422 Response

{
  "errors": [
    "Either subscriber id or email address is required to add subscriber to sequence"
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns a 200 when the subscriber has already been added to the sequence Inline
201 Created Adds the subscriber to the sequence Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
404 Not Found Returns a 404 when the provided id does not exist Inline
422 Unprocessable Entity Returns a 422 with an error message when missing email address Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» subscriber object true none none
»» id integer true none none
»» first_name string true none none
»» email_address string true none none
»» state string true none none
»» created_at string true none none
»» added_at string true none none
»» fields object true none none

Status Code 201

Name Type Required Restrictions Description
» subscriber object true none none
»» id integer true none none
»» first_name string true none none
»» email_address string true none none
»» state string true none none
»» created_at string true none none
»» added_at string true none none
»» fields object true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 404

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 422

Name Type Required Restrictions Description
» errors [string] true none none

Add subscriber to sequence

Code samples

# You can also use wget
curl -X POST https://api.convertkit.com/v4/sequences/{sequence_id}/subscribers/{id} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'

const inputBody = '{}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/sequences/{sequence_id}/subscribers/{id}',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.post 'https://api.convertkit.com/v4/sequences/{sequence_id}/subscribers/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.post('https://api.convertkit.com/v4/sequences/{sequence_id}/subscribers/{id}', headers = headers)

print(r.json())

POST /v4/sequences/{sequence_id}/subscribers/{id}

Body parameter

{}

Parameters

Name In Type Required Description
Authorization header string true none
id path integer true none
sequence_id path integer true none
body body object false none

Example responses

200 Response

{
  "subscriber": {
    "id": 519,
    "first_name": "Alice",
    "email_address": "alice@convertkit.dev",
    "state": "active",
    "created_at": "2023-02-17T11:43:55Z",
    "added_at": "2023-02-17T11:43:55Z",
    "fields": {}
  }
}

201 Response

{
  "subscriber": {
    "id": 520,
    "first_name": "Alice",
    "email_address": "alice@convertkit.dev",
    "state": "active",
    "created_at": "2023-02-17T11:43:55Z",
    "added_at": "2023-02-17T11:43:55Z",
    "fields": {}
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

404 Response

{
  "errors": [
    "Not Found"
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns a 200 when the subscriber has already been added to the sequence Inline
201 Created Adds the subscriber to the sequence Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
404 Not Found Returns a 404 when the provided id does not exist Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» subscriber object true none none
»» id integer true none none
»» first_name string true none none
»» email_address string true none none
»» state string true none none
»» created_at string true none none
»» added_at string true none none
»» fields object true none none

Status Code 201

Name Type Required Restrictions Description
» subscriber object true none none
»» id integer true none none
»» first_name string true none none
»» email_address string true none none
»» state string true none none
»» created_at string true none none
»» added_at string true none none
»» fields object true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 404

Name Type Required Restrictions Description
» errors [string] true none none

Webhooks

List webhooks

Code samples

# You can also use wget
curl -X GET https://api.convertkit.com/v4/webhooks \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/webhooks',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.get 'https://api.convertkit.com/v4/webhooks',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.get('https://api.convertkit.com/v4/webhooks', headers = headers)

print(r.json())

GET /v4/webhooks

Webhooks are automations that will receive subscriber data when a subscriber event is triggered, such as when a subscriber completes a sequence.

When a webhook is triggered, a POST request will be made to your URL with a JSON payload.

Parameters

Name In Type Required Description
Authorization header string true none
after query any false To fetch next page of results, use ?after=<end_cursor>
before query any false To fetch previous page of results, use ?before=<start_cursor>
include_total_count query string false To include the total count of records in the response, use true. For large collections, expect a slightly slower response.
per_page query any false Number of results per page. Default 500, maximum 1000.

Example responses

200 Response

{
  "webhooks": [
    {
      "id": 2,
      "account_id": 528,
      "event": {
        "name": "tag_add",
        "tag_id": 11
      },
      "target_url": "http://example.convertkit.dev/tags"
    },
    {
      "id": 1,
      "account_id": 528,
      "event": {
        "name": "form_subscribe",
        "form_id": 8
      },
      "target_url": "http://example.convertkit.dev/"
    }
  ],
  "pagination": {
    "has_previous_page": false,
    "has_next_page": false,
    "start_cursor": "WzJd",
    "end_cursor": "WzFd",
    "per_page": 500
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns a paginated list of webhooks Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» webhooks [object] true none none
»» id integer true none none
»» account_id integer true none none
»» event object true none none
»»» name string true none none
»»» tag_id integer false none none
»»» form_id integer false none none
»»» sequence_id integer false none none
»»» product_id integer false none none
»»» initiator_value integer false none none
»» target_url string true none none
» pagination object true none none
»» has_previous_page boolean true none none
»» has_next_page boolean true none none
»» start_cursor string¦null true none none
»» end_cursor string¦null true none none
»» per_page integer true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Create a webhook

Code samples

# You can also use wget
curl -X POST https://api.convertkit.com/v4/webhooks \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'

const inputBody = '{
  "target_url": "string",
  "event": {
    "name": "string",
    "form_id": null,
    "tag_id": null,
    "course_id": null,
    "product_id": null,
    "initiator_value": null
  }
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/webhooks',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.post 'https://api.convertkit.com/v4/webhooks',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.post('https://api.convertkit.com/v4/webhooks', headers = headers)

print(r.json())

POST /v4/webhooks

Available event types:
- subscriber.subscriber_activate
- subscriber.subscriber_unsubscribe
- subscriber.subscriber_bounce
- subscriber.subscriber_complain
- subscriber.form_subscribe, required parameter form_id [Integer]
- subscriber.course_subscribe, required parameter course_id [Integer]
- subscriber.course_complete, required parameter course_id [Integer]
- subscriber.link_click, required parameter initiator_value [String] as a link URL
- subscriber.product_purchase, required parameter product_id [Integer]
- subscriber.tag_add, required parameter tag_id [Integer]
- subscriber.tag_remove, required parameter tag_id [Integer]
- purchase.purchase_create

Body parameter

{
  "target_url": "string",
  "event": {
    "name": "string",
    "form_id": null,
    "tag_id": null,
    "course_id": null,
    "product_id": null,
    "initiator_value": null
  }
}

Parameters

Name In Type Required Description
Authorization header string true none
body body object false none
» target_url body string true none
» event body object true none
»» name body string true The event type. Must be one of the available event types listed above.
»» form_id body any false none
»» tag_id body any false none
»» course_id body any false none
»» product_id body any false none
»» initiator_value body any false none

Example responses

201 Response

{
  "webhook": {
    "id": 7,
    "account_id": 536,
    "event": {
      "name": "subscriber_activate",
      "initiator_value": null
    },
    "target_url": "https://example.convertkit.dev/"
  }
}

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

Responses

Status Meaning Description Schema
201 Created Creates the webhook Inline
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline

Response Schema

Status Code 201

Name Type Required Restrictions Description
» webhook object true none none
»» id integer true none none
»» account_id integer true none none
»» event object true none none
»»» name string true none none
»»» initiator_value any true none none
»» target_url string true none none

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Delete a webhook

Code samples

# You can also use wget
curl -X DELETE https://api.convertkit.com/v4/webhooks/{id} \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -H 'Accept: ' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'

const inputBody = '{}';
const headers = {
  'Content-Type':'application/x-www-form-urlencoded',
  'Accept':'',
  'Authorization':'Bearer YOUR_ACCESS_TOKEN_HERE'
};

fetch('https://api.convertkit.com/v4/webhooks/{id}',
{
  method: 'DELETE',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/x-www-form-urlencoded',
  'Accept' => '',
  'Authorization' => 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

result = RestClient.delete 'https://api.convertkit.com/v4/webhooks/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/x-www-form-urlencoded',
  'Accept': '',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN_HERE'
}

r = requests.delete('https://api.convertkit.com/v4/webhooks/{id}', headers = headers)

print(r.json())

DELETE /v4/webhooks/{id}

Body parameter

{}

Parameters

Name In Type Required Description
Authorization header string true none
id path integer true none
body body object false none

Example responses

204 Response

401 Response

{
  "errors": [
    "The access token is invalid"
  ]
}

404 Response

{
  "errors": [
    "Not Found"
  ]
}

Responses

Status Meaning Description Schema
204 No Content Deletes the webhook string
401 Unauthorized Returns a 401 if the token and/or account cannot be authenticated Inline
404 Not Found Returns a 404 when the provided id does not exist Inline

Response Schema

Status Code 401

Name Type Required Restrictions Description
» errors [string] true none none

Status Code 404

Name Type Required Restrictions Description
» errors [string] true none none