PHP用のSDKは存在しないため、これはREST APIを直接使います。それは見た目ほどの制約ではありません。このAPIはベアラートークンを使ったHTTPS上のプレーンなJSONであり、PHPの標準ライブラリだけで必要なことはすべて揃っています。
もしWordPressから公開しているのであれば、プラグインとRSS経由のルートがあり、これを自分で書くより手間が少ない場合があります。
認証
すべてのリクエストは、あなたのAPIキーをベアラートークンとして持ちます。
$apiKey = getenv('BULKPUBLISH_API_KEY');
$baseUrl = 'https://app.bulkpublish.com';
キーはソースコードやコミット済みの設定ファイルではなく、環境変数に保持してください。
下書きを作成する
$payload = [
'content' => 'Check out our latest update!',
'channels' => [
['channelId' => 1, 'platform' => 'x'],
['channelId' => 2, 'platform' => 'linkedin'],
],
'status' => 'draft',
];
$ch = curl_init("$baseUrl/api/posts");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
"Authorization: Bearer $apiKey",
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
error_log("BulkPublish error $status: $response");
} else {
$post = json_decode($response, true);
}
まずはdraftから始めましょう。アプリ内に表示されるため、何かが公開される前に、自分のコードが何を作ったのかを確認できます。
Guzzleを使う場合も同様
すでにGuzzleを使っているなら、こちらのほうがすっきりします。
use GuzzleHttp\Client;
$client = new Client([
'base_uri' => 'https://app.bulkpublish.com',
'headers' => [
'Authorization' => 'Bearer ' . getenv('BULKPUBLISH_API_KEY'),
'Content-Type' => 'application/json',
],
]);
$response = $client->post('/api/posts', [
'json' => [
'content' => 'Check out our new feature!',
'channels' => [['channelId' => 1, 'platform' => 'instagram']],
'status' => 'scheduled',
'scheduledAt' => '2026-04-10T14:00:00Z',
'timezone' => 'America/New_York',
],
]);
$post = json_decode((string) $response->getBody(), true);
チャンネルIDを調べる
$response = $client->get('/api/channels');
$channels = json_decode((string) $response->getBody(), true);
調べておくか、設定として保持しておきましょう。使い捨てスクリプトから取ったIDを長く使うものにハードコーディングすることが、デプロイで間違ったアカウントに投稿してしまう原因になります。
予約に関するフィールド
scheduledAtはISO-8601形式のタイムスタンプで、timezoneはIANA名です。繰り返し投稿する場合はタイムゾーンを明示的に渡してください。そうしないと、夏時間が切り替わったときに投稿時刻が1時間ずれてしまいます。
エラーをきちんと処理する
サーバーサイドでの公開に特有の失敗パターンは、誰も見ていないということです。午前3時にバリデーションに失敗した投稿は、あなたがそれを目立たせない限り静かに終わります。
- ステータスコードを確認する:レスポンスボディがあることを成功だと思い込まない
- 失敗時はレスポンスボディをログに残す:何が問題だったかはそこに書かれている
- レート制限を守る:即座にリトライするのではなくバックオフする
| Free | Pro | Business | |
|---|---|---|---|
| APIリクエスト/日 | 30 | 5,000 | 50,000 |
| APIキー | 1 | 5 | 10 |
| Freeの1日30回は評価用です。スケジュール実行するものには有料プランが必要です。 |
まとめ
SDKは不要です。ベアラートークンとともに、content、channels、statusを含むJSONを/api/postsにPOSTしてください。下書きから始め、チャンネルIDを調べ、予約投稿にはタイムゾーンを渡し、失敗をきちんとログに残しましょう。サーバーサイドでの公開はデフォルトでは静かに失敗するからです。