権限のある public platform アカウントのプロフィールを一括更新する方法

著者:TwexAPI チーム
JA
他の言語:
日本語
English中文
TwexAPI
public platform プロフィール
権限付きアカウント管理
一括更新
Python
Node.js
API チュートリアル

TwexAPI で、権限のある public platform アカウントの name、description、location、website、画像、banner を更新します。まず 1 アカウントで検証し、その後 Python または Node.js で小さく一括実行します。

Quick Answer

TwexAPI の public platform プロフィール更新 endpoint(/twitter/profile)は、所有または管理許可のある public platform アカウントの profile field を更新します。低リスクの 1 アカウントで検証し、小さい concurrency で実行し、cookie と結果ログを保護します。 api.twexapi.io で Bearer 認証します。通常の read は 5 Credits(約 $0.05/1K)で、対象プランは 20+ QPS を公開しています。新規アカウントには 20,000 starting Credits が付与されます。詳細は本記事と https://docs.twexapi.io を参照してください。

FAQ

public platform プロフィール更新 エンドポイントは何を返しますか?

所有または管理許可のある public platform アカウントの profile field を更新します。低リスクの 1 アカウントで検証し、小さい concurrency で実行し、cookie と結果ログを保護します。

この用途で公式 public social data API ではなく TwexAPI を使う理由は?

public platform プロフィール更新 では https://docs.twexapi.io に記載された TwexAPI Bearer workflow を利用できます。通常の Post/Profile read は 5 Credits(約 $0.05/1K)で、対象プランは 20+ QPS を公開しています。新規アカウントには 20,000 starting Credits が付与されます。2026-08-20 時点の公式 Post/User read は $5/$10 per 1K で、rate limit は endpoint ごとに異なります。

TwexAPI でこのワークフローのコストは?

通常の読み取りは約 5 Credits です。公開換算では 1,000 回で 5,000 Credits(約 $0.05)、10,000 回で約 50,000 Credits です。実際の cost は endpoint ごとに異なるため https://twexapi.io/pricing を確認してください。

1 つの X アカウントだけなら、プロフィールは手作業で変更しても大きな問題になりません。大変なのは、ブランドアカウント、地域別サポートアカウント、製品アカウント、キャンペーン用アカウントをまとめて更新する場合です。name、description、location、画像、banner をそろえる必要があり、1 つでも漏れると古い告知や古い画像が残ってしまいます。

TwexAPI のプロフィール更新 APIは、このような繰り返し作業に向いています。安全に進めるなら、最初に 1 アカウントで検証し、同じリクエストを小さな並列数のバッチ処理に移し、最後にアカウントごとの実行結果を残します。

この手順は、所有している、または管理権限を付与された X アカウントにのみ使用してください。アカウント Cookie はパスワードと同様に扱ってください。

一括更新の進め方

Answer: 一括更新の進め方とは、この事例で api.twexapi.io の TwexAPI Bearer API を使う手順です。通常の読み取りは 5 Credits(約 $0.05/1K)、対象プランは 20+ QPS です。2026-08-20 時点の公式 Post/User read は $5/$10 per 1K で、rate limit は endpoint ごとに異なります。

プロフィール更新は、アカウント一覧をそのままループに流す作業ではなく、管理されたメンテナンス作業として扱います。API 呼び出し自体は単純です。TwexAPI Bearer Token で POST https://api.twexapi.io/twitter/profile を呼び出し、対象アカウントの cookie と、この実行で変更を許可する項目だけを送信します。

安全な一括更新では、次の 4 点を決めておきます。

  • まず低リスクの 1 アカウントを更新し、実際の X プロフィール表示を確認する。
  • アカウントごとにローカル設定を 1 行ずつ持ち、updates には今回変更する項目だけを入れる。
  • 並列数は 2 から 3 worker 程度に抑え、失敗原因を追いやすくする。
  • 各アカウントの成功、失敗理由、リトライ回数、実行時刻を結果ファイルに残す。

プロフィール変更には専用のプレビューエンドポイントがありません。実質的な dry run は、設定を人が確認し、低リスクの 1 アカウントだけを更新し、実際の X 表示を確認することです。

API エンドポイント

Answer: API エンドポイントは本ガイドの TwexAPI エンドポイントを Bearer で呼び出して実装します。バッチ/ページングで約 5 Credits/回・20+ QPS です。

POST https://api.twexapi.io/twitter/profile

Authorization: Bearer <your_twexapi_token>
Content-Type: application/json

リクエストボディでは次のフィールドを使用できます。

フィールド必須用途
cookieはい更新対象 X アカウントのログイン済み Cookie 文字列
nameいいえ表示名
websiteいいえプロフィールの Web サイト URL
descriptionいいえプロフィールの自己紹介
locationいいえプロフィールの地域
profile_imageいいえプロフィール画像 URL
profile_bannerいいえBanner 画像 URL
proxy注記参照このリクエストで使うプロキシ URL

エンドポイントの schema では proxy は nullable と表示されていますが、フィールド説明では住宅プロキシが求められています。一括処理では軽く扱わない方が安全です。TwexAPI サポートから省略可能と案内されていない限り、アカウントごとに安定したプロキシを指定してください。失敗したときに、Cookie、プロキシ、画像 URL、リクエスト項目のどこに原因があるかを切り分けやすくなります。

更新に成功すると、次のレスポンスが返ります。

{
  "code": 200,
  "msg": "success",
  "data": true
}

まず 1 つの X アカウントを更新する

Answer: まず 1 つの public platform アカウントを更新するとは、この事例で api.twexapi.io の TwexAPI Bearer API を使う手順です。通常の読み取りは 5 Credits(約 $0.05/1K)、対象プランは 20+ QPS です。2026-08-20 時点の公式 Post/User read は $5/$10 per 1K で、rate limit は endpoint ごとに異なります。

最初はリスクの低い 1 アカウントで、リクエスト全体を確認します。TwexAPI Token はソースコードに直接書かず、環境変数に設定します。

export TWEXAPI_TOKEN="your_twexapi_bearer_token"

次に、変更したい項目だけを送信します。

1curl --request POST \
2  --url https://api.twexapi.io/twitter/profile \
3  --header "Authorization: Bearer $TWEXAPI_TOKEN" \
4  --header "Content-Type: application/json" \
5  --data '{
6    "cookie": "auth_token=...; ct0=...; twid=...",
7    "proxy": "http://username:[email protected]:8000",
8    "name": "Acme Support",
9    "description": "Product help, release notes, and service updates.",
10    "location": "New York",
11    "website": "https://example.com/support",
12    "profile_image": "https://example.com/assets/support-avatar.png",
13    "profile_banner": "https://example.com/assets/support-banner.png"
14  }'

この 1 回目のリクエストで、Cookie がまだ有効か、プロキシが使えるか、画像 URL が公開アクセスできるかを確認できます。成功してから一括更新に進んでください。

変更が必要な値だけを含めます。たとえばテキスト情報のみ更新する場合は、profile_image と profile_banner を省略します。古い値を設定ファイルに残すと、バッチ処理はその値をそのまま書き戻します。

一括更新用の設定ファイルを準備する

Answer: 一括更新用の設定ファイルを準備するとは、この事例で api.twexapi.io の TwexAPI Bearer API を使う手順です。通常の読み取りは 5 Credits(約 $0.05/1K)、対象プランは 20+ QPS です。2026-08-20 時点の公式 Post/User read は $5/$10 per 1K で、rate limit は endpoint ごとに異なります。

ローカルに profiles.json を作成します。各オブジェクトが 1 アカウントを表し、updates には今回変更する項目だけを入れます。account_id はレポート用のローカルラベルであり、API には送信されません。

1[
2  {
3    "account_id": "acme-support-us",
4    "cookie": "auth_token=...; ct0=...; twid=...",
5    "proxy": "http://username:[email protected]:8000",
6    "updates": {
7      "name": "Acme Support US",
8      "description": "Product help and service updates for US customers.",
9      "location": "United States",
10      "website": "https://example.com/us/support",
11      "profile_image": "https://example.com/assets/us-avatar.png",
12      "profile_banner": "https://example.com/assets/us-banner.png"
13    }
14  },
15  {
16    "account_id": "acme-support-jp",
17    "cookie": "auth_token=...; ct0=...; twid=...",
18    "proxy": "http://username:[email protected]:8000",
19    "updates": {
20      "name": "Acme Support JP",
21      "description": "Product help and service updates for customers in Japan.",
22      "location": "Japan",
23      "website": "https://example.com/jp/support"
24    }
25  }
26]

profiles.json にはアカウント認証情報が含まれるため、バージョン管理に追加しないでください。ローカルプロジェクト内に置く必要がある場合は .gitignore に追加し、ファイル権限を制限します。

chmod 600 profiles.json

以下のスクリプトは、updates に明示されたキーだけを API に送信します。省略した項目は既存のプロフィール値を変更しません。フィールドを消去したい場合のみ、1 アカウントで動作確認を行った後に明示的な null を使ってください。

Python 一括更新スクリプト

Answer: Python 一括更新スクリプトとは、この事例で api.twexapi.io の TwexAPI Bearer API を使う手順です。通常の読み取りは 5 Credits(約 $0.05/1K)、対象プランは 20+ QPS です。2026-08-20 時点の公式 Post/User read は $5/$10 per 1K で、rate limit は endpoint ごとに異なります。

次のスクリプトは、各アカウントの cookie と updates を確認し、未対応のフィールドを拒否し、一時的な失敗を最大 3 回リトライし、結果を profile-update-results.json に書き出します。環境に requests がない場合はインストールします。

python -m pip install requests

次のスクリプトを batch-update-profiles.py として保存します。

1import json
2import os
3import time
4from concurrent.futures import ThreadPoolExecutor, as_completed
5
6import requests
7
8API_URL = "https://api.twexapi.io/twitter/profile"
9ALLOWED_FIELDS = {
10    "name",
11    "website",
12    "description",
13    "location",
14    "profile_image",
15    "profile_banner",
16}
17MAX_ATTEMPTS = 3
18MAX_WORKERS = 3
19
20token = os.environ.get("TWEXAPI_TOKEN")
21if not token:
22    raise RuntimeError("Missing TWEXAPI_TOKEN environment variable.")
23
24def build_body(account):
25    account_id = account.get("account_id", "unnamed-account")
26    cookie = account.get("cookie")
27    updates = account.get("updates")
28
29    if not cookie:
30        raise ValueError(f"{account_id}: missing cookie")
31    if not isinstance(updates, dict) or not updates:
32        raise ValueError(f"{account_id}: updates must be a non-empty object")
33
34    unknown_fields = sorted(set(updates) - ALLOWED_FIELDS)
35    if unknown_fields:
36        raise ValueError(f"{account_id}: unsupported fields: {unknown_fields}")
37
38    body = {"cookie": cookie, **updates}
39    if account.get("proxy"):
40        body["proxy"] = account["proxy"]
41    return body
42
43def update_profile(account):
44    account_id = account.get("account_id", "unnamed-account")
45
46    try:
47        body = build_body(account)
48    except ValueError as error:
49        return {"account_id": account_id, "ok": False, "error": str(error)}
50
51    for attempt in range(1, MAX_ATTEMPTS + 1):
52        try:
53            response = requests.post(
54                API_URL,
55                headers={"Authorization": f"Bearer {token}"},
56                json=body,
57                timeout=45,
58            )
59            payload = response.json()
60
61            if response.ok and payload.get("code") == 200 and payload.get("data") is True:
62                return {"account_id": account_id, "ok": True, "attempts": attempt}
63
64            message = str(payload.get("msg", f"HTTP {response.status_code}"))
65            retryable = response.status_code == 429 or response.status_code >= 500
66            if not retryable:
67                return {"account_id": account_id, "ok": False, "error": message}
68        except (requests.RequestException, ValueError) as error:
69            message = f"{type(error).__name__}: request failed"
70
71        if attempt < MAX_ATTEMPTS:
72            time.sleep(attempt * 2)
73
74    return {
75        "account_id": account_id,
76        "ok": False,
77        "error": message,
78        "attempts": MAX_ATTEMPTS,
79    }
80
81with open("profiles.json", encoding="utf-8") as source:
82    accounts = json.load(source)
83
84if not isinstance(accounts, list) or not accounts:
85    raise RuntimeError("profiles.json must contain a non-empty array.")
86
87results = []
88with ThreadPoolExecutor(max_workers=min(MAX_WORKERS, len(accounts))) as executor:
89    futures = [executor.submit(update_profile, account) for account in accounts]
90    for future in as_completed(futures):
91        result = future.result()
92        results.append(result)
93        print(f"{result['account_id']}: {'updated' if result['ok'] else 'failed'}")
94
95with open("profile-update-results.json", "w", encoding="utf-8") as output:
96    json.dump(results, output, ensure_ascii=False, indent=2)
97
98success_count = sum(1 for result in results if result["ok"])
99print(f"Finished: {success_count}/{len(results)} profiles updated.")

実行方法:

TWEXAPI_TOKEN="your_twexapi_bearer_token" python batch-update-profiles.py

初回は profiles.json に 1 から 2 アカウントだけ残して実行してください。結果ファイル、実際の X プロフィール、画像の読み込みを確認してから、全件に広げます。

Node.js 一括更新スクリプト

Answer: Node.js 一括更新スクリプトとは、この事例で api.twexapi.io の TwexAPI Bearer API を使う手順です。通常の読み取りは 5 Credits(約 $0.05/1K)、対象プランは 20+ QPS です。2026-08-20 時点の公式 Post/User read は $5/$10 per 1K で、rate limit は endpoint ごとに異なります。

Node.js を使うチーム向けの版です。Node.js 18 以降には fetch が組み込まれているため、追加パッケージは不要です。次のスクリプトを batch-update-profiles.mjs として保存します。

1import { readFile, writeFile } from "node:fs/promises";
2
3const API_URL = "https://api.twexapi.io/twitter/profile";
4const ALLOWED_FIELDS = new Set([
5  "name",
6  "website",
7  "description",
8  "location",
9  "profile_image",
10  "profile_banner",
11]);
12const MAX_ATTEMPTS = 3;
13const MAX_WORKERS = 3;
14const token = process.env.TWEXAPI_TOKEN;
15
16if (!token) {
17  throw new Error("Missing TWEXAPI_TOKEN environment variable.");
18}
19
20const sleep = (milliseconds) =>
21  new Promise((resolve) => setTimeout(resolve, milliseconds));
22
23function buildBody(account) {
24  const accountId = account.account_id || "unnamed-account";
25  const updates = account.updates;
26
27  if (!account.cookie) {
28    throw new Error(`${accountId}: missing cookie`);
29  }
30  if (!updates || typeof updates !== "object" || Array.isArray(updates)) {
31    throw new Error(`${accountId}: updates must be a non-empty object`);
32  }
33
34  const updateKeys = Object.keys(updates);
35  if (updateKeys.length === 0) {
36    throw new Error(`${accountId}: updates must be a non-empty object`);
37  }
38
39  const unknownFields = updateKeys.filter((key) => !ALLOWED_FIELDS.has(key));
40  if (unknownFields.length > 0) {
41    throw new Error(`${accountId}: unsupported fields: ${unknownFields.join(", ")}`);
42  }
43
44  return {
45    cookie: account.cookie,
46    ...(account.proxy ? { proxy: account.proxy } : {}),
47    ...updates,
48  };
49}
50
51async function updateProfile(account) {
52  const accountId = account.account_id || "unnamed-account";
53  let body;
54
55  try {
56    body = buildBody(account);
57  } catch (error) {
58    return { account_id: accountId, ok: false, error: error.message };
59  }
60
61  let message = "request failed";
62  for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt += 1) {
63    try {
64      const response = await fetch(API_URL, {
65        method: "POST",
66        headers: {
67          Authorization: `Bearer ${token}`,
68          "Content-Type": "application/json",
69        },
70        body: JSON.stringify(body),
71        signal: AbortSignal.timeout(45_000),
72      });
73      const payload = await response.json().catch(() => ({}));
74
75      if (response.ok && payload.code === 200 && payload.data === true) {
76        return { account_id: accountId, ok: true, attempts: attempt };
77      }
78
79      message = String(payload.msg || `HTTP ${response.status}`);
80      const retryable = response.status === 429 || response.status >= 500;
81      if (!retryable) {
82        return { account_id: accountId, ok: false, error: message };
83      }
84    } catch (error) {
85      message = `${error.name}: request failed`;
86    }
87
88    if (attempt < MAX_ATTEMPTS) {
89      await sleep(attempt * 2_000);
90    }
91  }
92
93  return { account_id: accountId, ok: false, error: message, attempts: MAX_ATTEMPTS };
94}
95
96async function runQueue(accounts, workerCount) {
97  const results = new Array(accounts.length);
98  let cursor = 0;
99
100  async function worker() {
101    while (cursor < accounts.length) {
102      const index = cursor;
103      cursor += 1;
104      results[index] = await updateProfile(accounts[index]);
105      console.log(`${results[index].account_id}: ${results[index].ok ? "updated" : "failed"}`);
106    }
107  }
108
109  await Promise.all(
110    Array.from({ length: Math.min(workerCount, accounts.length) }, () => worker()),
111  );
112  return results;
113}
114
115const accounts = JSON.parse(await readFile("profiles.json", "utf8"));
116if (!Array.isArray(accounts) || accounts.length === 0) {
117  throw new Error("profiles.json must contain a non-empty array.");
118}
119
120const results = await runQueue(accounts, MAX_WORKERS);
121await writeFile("profile-update-results.json", JSON.stringify(results, null, 2));
122
123const successCount = results.filter((result) => result.ok).length;
124console.log(`Finished: ${successCount}/${results.length} profiles updated.`);

実行方法:

TWEXAPI_TOKEN="your_twexapi_bearer_token" node batch-update-profiles.mjs

本番運用チェックリスト

Answer: 本番運用チェックリストとは、この事例で api.twexapi.io の TwexAPI Bearer API を使う手順です。通常の読み取りは 5 Credits(約 $0.05/1K)、対象プランは 20+ QPS です。2026-08-20 時点の公式 Post/User read は $5/$10 per 1K で、rate limit は endpoint ごとに異なります。

  • 管理権限を持つアカウントにのみ、この手順を使ってください。
  • TWEXAPI_TOKEN は環境変数またはシークレット管理サービスに保存してください。
  • X Cookie と認証情報を含むプロキシ URL は、ソース管理の外に保存してください。
  • Cookie やプロキシ認証情報をログやレポートに出力しないでください。
  • 最初に 1 アカウントで確認し、次に小さなバッチでテストしてから規模を拡大してください。
  • 並列数は小さく保ってください。worker を急に増やすと、失敗原因の調査が難しくなります。
  • リトライするのは、ネットワーク障害、HTTP 429、HTTP 5xx だけにしてください。フィールドエラーや認証エラーは、原因を直してから再実行します。
  • 各実行後に profile-update-results.json を確認し、監査記録として保管してください。
  • profile_image と profile_banner には、安定して公開アクセスできる画像 URL を使ってください。

関連リソース

Answer: 関連リソースとは、この事例で api.twexapi.io の TwexAPI Bearer API を使う手順です。通常の読み取りは 5 Credits(約 $0.05/1K)、対象プランは 20+ QPS です。2026-08-20 時点の公式 Post/User read は $5/$10 per 1K で、rate limit は endpoint ごとに異なります。

権限のある public platform アカウントのプロフィールを一括更新する方法