Skip to content

Add v4 API Key Support #105

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Apr 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ jobs:
CONVERTKIT_OAUTH_REFRESH_TOKEN=${{ secrets.CONVERTKIT_OAUTH_REFRESH_TOKEN }}
CONVERTKIT_OAUTH_ACCESS_TOKEN_NO_DATA=${{ secrets.CONVERTKIT_OAUTH_ACCESS_TOKEN_NO_DATA }}
CONVERTKIT_OAUTH_REFRESH_TOKEN_NO_DATA=${{ secrets.CONVERTKIT_OAUTH_REFRESH_TOKEN_NO_DATA }}
CONVERTKIT_API_KEY=${{ secrets.CONVERTKIT_API_KEY }}
CONVERTKIT_OAUTH_CLIENT_ID=${{ secrets.CONVERTKIT_OAUTH_CLIENT_ID }}
CONVERTKIT_OAUTH_CLIENT_SECRET=${{ secrets.CONVERTKIT_OAUTH_CLIENT_SECRET }}
CONVERTKIT_OAUTH_REDIRECT_URI=${{ secrets.CONVERTKIT_OAUTH_REDIRECT_URI }}
Expand Down
37 changes: 26 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ConvertKit SDK PHP
# Kit SDK PHP

The ConvertKit PHP SDK provides convinient access to the ConvertKit API from applications written in the PHP language.
The Kit PHP SDK provides convinient access to the Kit API from applications written in the PHP language.

It includes a pre-defined set of methods for interacting with the API.

Expand All @@ -10,6 +10,7 @@ It includes a pre-defined set of methods for interacting with the API.
|-------------|-------------|--------------------|--------------|
| 1.x | v3 | API Key and Secret | 7.4+ |
| 2.x | v4 | OAuth | 8.0+ |
| 2.2+ | v4 | API Key | 8.0+ |

Refer to [this guide](MIGRATION.md) for changes when upgrading to the v2 SDK.

Expand Down Expand Up @@ -41,9 +42,9 @@ If you use Composer, these dependencies should be handled automatically.

### 2.x (v4 API, OAuth, PHP 8.0+)

First, register your OAuth application in the `OAuth Applications` section at https://app.convertkit.com/account_settings/advanced_settings.
First, register your OAuth application in the `OAuth Applications` section at https://app.kit.com/account_settings/advanced_settings.

Using the supplied Client ID and secret, redirect the user to ConvertKit to grant your application access to their ConvertKit account.
Using the supplied Client ID and secret, redirect the user to Kit to grant your application access to their Kit account.

```php
// Require the autoloader (if you're using a PHP framework, this may already be done for you).
Expand All @@ -59,7 +60,7 @@ $api = new \ConvertKit_API\ConvertKit_API(
header('Location: '.$api->get_oauth_url('<your_redirect_uri>'));
```

Once the user grants your application access to their ConvertKit account, they'll be redirected to your Redirect URI with an authorization code. For example:
Once the user grants your application access to their Kit account, they'll be redirected to your Redirect URI with an authorization code. For example:

`your-redirect-uri?code=<auth_code>`

Expand Down Expand Up @@ -118,26 +119,40 @@ $api = new \ConvertKit_API\ConvertKit_API(
API requests may then be performed:

```php
$result = $api->add_subscriber_to_form(12345, 'joe.bloggs@convertkit.com');
$result = $api->add_subscriber_to_form(12345, 'joe.bloggs@kit.com');
```

To determine whether a new entity / relationship was created, or an existing entity / relationship updated, inspect the HTTP code of the last request:

```php
$result = $api->add_subscriber_to_form(12345, 'joe.bloggs@convertkit.com');
$result = $api->add_subscriber_to_form(12345, 'joe.bloggs@kit.com');
$code = $api->getResponseInterface()->getStatusCode(); // 200 OK if e.g. a subscriber already added to the specified form, 201 Created if the subscriber added to the specified form for the first time.
```

The PSR-7 response can be fetched and further inspected, if required - for example, to check if a header exists:

```php
$result = $api->add_subscriber_to_form(12345, 'joe.bloggs@convertkit.com');
$result = $api->add_subscriber_to_form(12345, 'joe.bloggs@kit.com');
$api->getResponseInterface()->hasHeader('Content-Length'); // Check if the last API request included a `Content-Length` header
```

### 2.2+ (v4 API, API Key, PHP 8.0+)

Get your Kit API Key and API Secret [here](https://app.kit.com/account_settings/developer_settings) and set it somewhere in your application.

```php
// Require the autoloader (if you're using a PHP framework, this may already be done for you).
require_once 'vendor/autoload.php';

// Initialize the API class.
$api = new \ConvertKit_API\ConvertKit_API(
apiKey: '<your_v4_api_key>'
);
```

### 1.x (v3 API, API Key and Secret, PHP 7.4+)

Get your ConvertKit API Key and API Secret [here](https://app.convertkit.com/account/edit) and set it somewhere in your application.
Get your Kit API Key and API Secret [here](https://app.kit.com/account_settings/developer_settings) and set it somewhere in your application.

```php
// Require the autoloader (if you're using a PHP framework, this may already be done for you).
Expand All @@ -149,7 +164,7 @@ $api = new \ConvertKit_API\ConvertKit_API('<your_public_api_key>', '<your_secret

## Handling Errors

The ConvertKit PHP SDK uses Guzzle for all HTTP API requests. Errors will be thrown as Guzzle's `ClientException` (for 4xx errors),
The Kit PHP SDK uses Guzzle for all HTTP API requests. Errors will be thrown as Guzzle's `ClientException` (for 4xx errors),
or `ServerException` (for 5xx errors).

```php
Expand Down Expand Up @@ -190,4 +205,4 @@ See the [PHP SDK docs](./docs/classes/ConvertKit_API/ConvertKit_API.md)

See our [contributor guide](CONTRIBUTING.md) for setting up your development environment, testing and submitting a PR.

For ConvertKit, refer to the [deployment guide](DEPLOYMENT.md) on how to publish a new release.
For Kit, refer to the [deployment guide](DEPLOYMENT.md) on how to publish a new release.
5 changes: 5 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@
"ConvertKit_API\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"": "tests/"
}
},
"minimum-stability": "dev",
"prefer-stable": true,
"scripts": {
Expand Down
1 change: 1 addition & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<testsuites>
<testsuite name="ConvertKit API Tests">
<directory>tests</directory>
<exclude>tests/ConvertKitAPITest.php</exclude>
</testsuite>
</testsuites>
</phpunit>
59 changes: 40 additions & 19 deletions src/ConvertKit_API.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,19 +62,22 @@ class ConvertKit_API
* @param string $clientID OAuth Client ID.
* @param string $clientSecret OAuth Client Secret.
* @param string $accessToken OAuth Access Token.
* @param string $apiKey API Key.
* @param boolean $debug Log requests to debugger.
* @param string $debugLogFileLocation Path and filename of debug file to write to.
*/
public function __construct(
string $clientID,
string $clientSecret,
string $clientID = '',
string $clientSecret = '',
string $accessToken = '',
string $apiKey = '',
bool $debug = false,
string $debugLogFileLocation = ''
) {
$this->client_id = $clientID;
$this->client_secret = $clientSecret;
$this->access_token = $accessToken;
$this->api_key = $apiKey;
$this->debug = $debug;

// Set the Guzzle client.
Expand Down Expand Up @@ -122,22 +125,35 @@ private function create_log(string $message)
return;
}

// Mask the Client ID, Client Secret and Access Token.
$message = str_replace(
$this->client_id,
str_repeat('*', (strlen($this->client_id) - 4)) . substr($this->client_id, - 4),
$message
);
$message = str_replace(
$this->client_secret,
str_repeat('*', (strlen($this->client_secret) - 4)) . substr($this->client_secret, - 4),
$message
);
$message = str_replace(
$this->access_token,
str_repeat('*', (strlen($this->access_token) - 4)) . substr($this->access_token, - 4),
$message
);
// Mask the Client ID, Client Secret, Access Token, and API Key.
if ($this->client_id) {
$message = str_replace(
$this->client_id,
str_repeat('*', (strlen($this->client_id) - 4)) . substr($this->client_id, - 4),
$message
);
}
if ($this->client_secret) {
$message = str_replace(
$this->client_secret,
str_repeat('*', (strlen($this->client_secret) - 4)) . substr($this->client_secret, - 4),
$message
);
}
if ($this->access_token) {
$message = str_replace(
$this->access_token,
str_repeat('*', (strlen($this->access_token) - 4)) . substr($this->access_token, - 4),
$message
);
}
if ($this->api_key) {
$message = str_replace(
$this->api_key,
str_repeat('*', (strlen($this->api_key) - 4)) . substr($this->api_key, - 4),
$message
);
}

// Mask email addresses that may be contained within the message.
$message = preg_replace_callback(
Expand Down Expand Up @@ -427,7 +443,12 @@ public function get_request_headers(string $type = 'application/json', bool $aut
}

// Add authorization header and return.
$headers['Authorization'] = 'Bearer ' . $this->access_token;
if ($this->api_key) {
$headers['X-Kit-Api-Key'] = $this->api_key;
} else if ($this->access_token) {
$headers['Authorization'] = 'Bearer ' . $this->access_token;
}

return $headers;
}

Expand Down
7 changes: 7 additions & 0 deletions src/ConvertKit_API_Traits.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ trait ConvertKit_API_Traits
*/
protected $access_token = '';

/**
* API Key
*
* @var string
*/
protected $api_key = '';

/**
* OAuth Authorization URL
*
Expand Down
Loading