{
  "schemaVersion": "1.0",
  "item": {
    "slug": "telnyx-freemium-upgrade",
    "name": "Telnyx Freemium Upgrade",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/teamtelnyx/telnyx-freemium-upgrade",
    "canonicalUrl": "https://clawhub.ai/teamtelnyx/telnyx-freemium-upgrade",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/telnyx-freemium-upgrade",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=telnyx-freemium-upgrade",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "SKILL.md",
      "scripts/check-gh-auth.sh",
      "scripts/evaluate-upgrade.py",
      "scripts/get-gh-token.sh",
      "scripts/refresh-gh-scopes.sh",
      "scripts/wait-for-auth.sh"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-05-07T17:22:31.273Z",
      "expiresAt": "2026-05-14T17:22:31.273Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=afrexai-annual-report",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=afrexai-annual-report",
        "contentDisposition": "attachment; filename=\"afrexai-annual-report-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/telnyx-freemium-upgrade"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/telnyx-freemium-upgrade",
    "agentPageUrl": "https://openagent3.xyz/skills/telnyx-freemium-upgrade/agent",
    "manifestUrl": "https://openagent3.xyz/skills/telnyx-freemium-upgrade/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/telnyx-freemium-upgrade/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "Companion Skills",
        "body": "This skill depends on telnyx-bot-signup for API key generation and refresh. If no Telnyx API key is available, or if the key needs to be refreshed after a successful upgrade, use telnyx-bot-signup to obtain one. The bot_signup endpoint handles both new and existing accounts — just provide the user's email.\n\nSkillWhen neededInstalltelnyx-bot-signupNo API key available, or key refresh needed post-upgradeclawhub install telnyx-bot-signup"
      },
      {
        "title": "When to Activate",
        "body": "This skill triggers when the bot encounters a freemium-blocked operation. Activate when ANY of these conditions occur:"
      },
      {
        "title": "Automatic Triggers (API Error Codes)",
        "body": "Error CodeContextMeaning10039SMS sendDestination not verified (freemium restriction)D60Voice callDestination not verified (freemium restriction)10038VariousFeature not available on current plan (porting, short codes, number lookup, SIM, managed accounts, etc.)"
      },
      {
        "title": "Heuristic Triggers (Capacity Limits)",
        "body": "Phone number order fails after the first purchase (1 number limit)\nBalance/credit check returns low available credit ($10 ceiling)\nInability to add funds / top up balance — freemium accounts cannot add balance or payment methods. If the bot encounters an error when trying to add funds, check account tier, or top up, and the account is freemium, this is a strong signal that an upgrade is needed.\nAccount shows as \"inactive\" or \"deactivated\" due to $0 balance on freemium tier"
      },
      {
        "title": "Explicit Triggers",
        "body": "User requests an upgrade: \"upgrade my account\", \"I need professional tier\"\nBot needs a non-freemium feature: \"send SMS to unverified number\", \"port a number\", \"create a managed account\"\nUser or bot tries to add balance/payment and is blocked by freemium restrictions"
      },
      {
        "title": "Verification Methods",
        "body": "Two verification methods are available. Each can only be used once per account.\n\nMethodFlagBrowser?Best forGitHub--github-token <TOKEN>No (automated)Users with gh CLI installedLinkedIn--linkedinYes (OAuth consent)Users without GitHub, or after GitHub rejection"
      },
      {
        "title": "Method Selection Decision Tree",
        "body": "Which method to try?\n├── Check ~/.telnyx/upgrade.json cache\n│   ├── decision: APPROVED → Already upgraded, skip\n│   ├── decision: PASS_TO_HUMAN → Under review, don't retry\n│   └── decision: REJECTED or no cache → Continue\n│\n├── Check used_methods in cache or status endpoint\n│   ├── github_oauth NOT used → Try GitHub first (automated, no browser)\n│   ├── github_oauth used, linkedin_oauth NOT used → Try LinkedIn\n│   └── Both used → Both methods exhausted, contact support\n│\n└── No preference → Try GitHub first (faster, no browser needed)"
      },
      {
        "title": "LinkedIn Verification Method",
        "body": "When to use: User has no GitHub account, GitHub method was REJECTED, or user prefers LinkedIn.\n\nFlow:\n\n1. python3 {baseDir}/scripts/evaluate-upgrade.py --linkedin\n   → Returns { action: \"open_url\", url: \"<linkedin_oauth_url>\" }\n\n2. Present the URL to the user:\n   \"To verify your identity, please open this link and sign in with LinkedIn:\n    <url>\n    After authorizing, you can close the browser tab.\"\n\n3. The script polls automatically. When the evaluation completes, it outputs\n   the result JSON (same format as GitHub).\n\n4. Handle outcome: APPROVED / REJECTED / PASS_TO_HUMAN (same as GitHub)\n\nNotification templates for LinkedIn URL:\n\nTelegram:\n\n🔗 Telnyx Account Upgrade — LinkedIn Verification\n\nI need to verify your identity via LinkedIn to upgrade your Telnyx account. This is a one-time step.\n\n👉 Open: <URL>\n⏰ Link expires in 10 minutes\n\nSign in with your LinkedIn account when prompted. After authorizing, you can close the tab.\n\nSlack:\n\n:link: *Telnyx Account Upgrade — LinkedIn Verification*\n\nI need to verify your identity via LinkedIn to upgrade your Telnyx account. This is a one-time step.\n\n:point_right: <URL|Open LinkedIn Verification>\n:timer_clock: Link expires in 10 minutes\n\nSign in with your LinkedIn account when prompted. After authorizing, you can close the tab."
      },
      {
        "title": "Pre-flight Checks (ALWAYS do these first)",
        "body": "Before submitting a new evaluation:"
      },
      {
        "title": "1. Check Local Cache",
        "body": "Read ~/.telnyx/upgrade.json. If it exists:\n\ndecision: \"APPROVED\" → Skip evaluation entirely. The account is already upgraded. Retry the blocked operation directly.\ndecision: \"PASS_TO_HUMAN\" → Re-poll the status endpoint with the cached evaluation_id to check if a decision was made. Do NOT submit a new evaluation.\ndecision: \"REJECTED\" → Check used_methods:\n\nOnly github_oauth used → Try LinkedIn: python3 {baseDir}/scripts/evaluate-upgrade.py --linkedin\nOnly linkedin_oauth used → Try GitHub: python3 {baseDir}/scripts/evaluate-upgrade.py --github-token <TOKEN>\nBoth used → All methods exhausted. Contact support.\n\n\nstatus: \"polling_timeout\" → Re-poll the cached evaluation_id. The evaluation may have completed server-side."
      },
      {
        "title": "2. Check used_methods via Status Endpoint",
        "body": "If no cache or cache is stale, poll GET /v2/account/upgrade-request-status/{evaluation_id} (if you have an evaluation_id) or check the latest evaluation. Check which methods have been used and follow the decision tree above."
      },
      {
        "title": "Token Type Detection and Handling",
        "body": "Run {baseDir}/scripts/check-gh-auth.sh to get token info. Handle based on token_type:"
      },
      {
        "title": "ghs_ (GitHub App Installation Token) → ABORT",
        "body": "These tokens represent a GitHub App, NOT a human user. Cannot verify human identity.\n\nTell the user:\n\nYour GitHub CLI is authenticated with a GitHub App installation token (commonly used in CI/CD environments). This token type cannot access user profile data needed for identity verification.\nTo proceed, please authenticate with your personal GitHub account:\ngh auth login --web\n\nThis will not affect your CI/CD workflows — gh supports multiple accounts.\n\nSTOP — wait for user to re-authenticate, then retry."
      },
      {
        "title": "github_pat_ (Fine-grained PAT) → WARN and PROCEED",
        "body": "Fine-grained PATs have limited API access: /user/orgs returns empty, no GraphQL support. Evaluation will have degraded data.\n\nTell the user:\n\nYour GitHub CLI is using a fine-grained personal access token. Some profile data (organizations, GraphQL contributions) may be unavailable, which could affect your evaluation. For best results, run gh auth login --web to use a standard OAuth token.\n\nPROCEED with the token anyway — the evaluator handles partial data."
      },
      {
        "title": "gho_ or ghp_ (OAuth / Classic PAT) → CHECK SCOPES and PROCEED",
        "body": "These are compatible token types. Check scopes and refresh if needed."
      },
      {
        "title": "Scope Check and Refresh",
        "body": "Required scopes: user, read:org\n\nIf check-gh-auth.sh returns missing_scopes that is non-empty:\n\nRun {baseDir}/scripts/refresh-gh-scopes.sh\n\n\nCheck the output:\n\nsuccess: true → scopes refreshed without browser interaction. Continue to submission.\nrequires_browser: true + success: false → the device_code, verification_uri, and pid fields are returned. Deliver the device code to the user via the Notification Decision Tree below.\n\n\n\nAfter the user authorizes, run {baseDir}/scripts/wait-for-auth.sh to confirm the refresh completed:\n\nsuccess: true → scopes refreshed. Continue to submission.\nsuccess: false → device code expired or authorization was denied. Retry from step 1 (max 3 times).\n\nYou can also pass the PID directly: bash {baseDir}/scripts/wait-for-auth.sh --pid <PID>"
      },
      {
        "title": "Notification Decision Tree (Scope Refresh)",
        "body": "When the bot needs a scope refresh or token acquisition:\n\nSTART: Bot needs GitHub scope refresh\n│\n├── Is `gh` installed?\n│   ├── NO → Notify user: \"Install gh: https://cli.github.com\"\n│   │        OR offer manual PAT creation via github.com/settings/tokens\n│   │        INTERVENTION: MEDIUM\n│   │\n│   └── YES → Check token type (prefix)\n│       │\n│       ├── ghs_ (installation) → ABORT\n│       │   Notify user: \"Need personal GitHub auth, not CI/CD token\"\n│       │   INTERVENTION: MEDIUM\n│       │\n│       ├── github_pat_ (fine-grained) → WARN, proceed with degraded data\n│       │   Cannot refresh scopes on PATs → proceed as-is\n│       │   INTERVENTION: ZERO (but evaluation has less data)\n│       │\n│       └── gho_ / ghp_ (OAuth / classic PAT) → Check scopes\n│           │\n│           ├── Scopes OK → PROCEED directly to upgrade evaluation\n│           │   INTERVENTION: ZERO\n│           │\n│           └── Scopes missing → Need refresh\n│               │\n│               └── Send device code to user's active channel\n│                   │\n│                   ├── User reachable on Telegram/Slack/etc?\n│                   │   ├── YES → Send code + link (see Cross-Channel Notification)\n│                   │   │   INTERVENTION: MINIMAL (user taps link, enters code)\n│                   │   │\n│                   │   └── NO (offline) → Save state + heartbeat\n│                   │       INTERVENTION: DEFERRED"
      },
      {
        "title": "Cross-Channel Notification (Minimal Intervention)",
        "body": "Parse the device code from refresh-gh-scopes.sh output (device_code and verification_uri fields).\n\nSend to the user's active channel:\n\nTelegram:\n\n🔑 Telnyx Account Upgrade\n\nI need to verify your GitHub identity to upgrade your Telnyx account from freemium to professional tier. This is a one-time step.\n\n👉 Visit: https://github.com/login/device\n📝 Enter code: <DEVICE_CODE>\n⏰ Expires in 15 minutes\n\nTap the link above to open in your browser. You must be logged into GitHub.\n\nSlack:\n\n:key: *Telnyx Account Upgrade*\n\nI need to verify your GitHub identity to upgrade your Telnyx account. This is a one-time step.\n\n:point_right: <https://github.com/login/device|Open GitHub Device Authorization>\n:pencil: Enter code: `<DEVICE_CODE>`\n:timer_clock: Expires in 15 minutes\n\nYou must be logged into GitHub in your browser.\n\nSMS (last resort):\n\nTelnyx upgrade: enter code <DEVICE_CODE> at github.com/login/device within 15 min. Must be logged into GitHub.\n\nUse the user's last active channel (check OpenClaw config at ~/.openclaw/openclaw.json). Priority: Telegram > Slack > SMS."
      },
      {
        "title": "Deferred (User Offline)",
        "body": "If the user is unreachable:\n\nSave state to ~/.telnyx/upgrade.json:\n{\n  \"pending_action\": \"scope_refresh\",\n  \"reason\": \"missing_scopes\",\n  \"required_scopes\": [\"user\", \"read:org\"],\n  \"queued_at\": \"<ISO_TIMESTAMP>\",\n  \"original_task\": \"<description of what triggered the upgrade>\"\n}\n\n\n\nOn user return (next message to bot), respond:\n\nBefore we continue, I need to upgrade your Telnyx account to use [requested feature]. This requires a one-time GitHub verification. Ready to proceed?"
      },
      {
        "title": "Proactive Upgrade (Optional)",
        "body": "On first Telnyx API interaction or skill load, the bot MAY proactively check the account tier:\n\nIf freemium and no prior attempt:\n\nIf gho_ token with user scope already present → start upgrade silently in background. Notify user only on completion.\nIf scopes missing but token compatible → offer: \"I notice you're on Telnyx's freemium tier. Some features you might need require an upgrade. I can handle this now (takes ~2 min, needs GitHub verification) or we can do it later when you actually need it. Want me to proceed?\"\nIf gh not installed or ghs_ token → queue for later, don't interrupt.\n\n\nIf prior APPROVED → no action needed.\nIf prior REJECTED → inform only when user hits a freemium wall.\nIf prior PASS_TO_HUMAN → re-poll silently."
      },
      {
        "title": "Intent Analysis (Before API Call)",
        "body": "The bot can analyze the user's intent before making a Telnyx API call to proactively trigger the upgrade:\n\nUser saysBot infersAction\"Send SMS to +1-555-123-4567\"Will need non-freemium (unverified destination)Check tier → pre-upgrade if needed\"Port my number from AT&T\"Will need non-freemium (porting blocked)Check tier → pre-upgrade if needed\"Buy 5 phone numbers\"Will need non-freemium (1 number limit)Check tier → pre-upgrade if needed\"Set up a SIP trunk\"Will need non-freemium (SIM/SIP blocked)Check tier → pre-upgrade if needed\"Create a managed account\"Will need non-freemium (10038)Check tier → pre-upgrade if needed\"Check my balance\"Freemium OKNo action\"Buy a phone number\"Freemium OK (1st number)No action"
      },
      {
        "title": "API Key Resolution",
        "body": "The Telnyx API key is resolved in this order:\n\nTELNYX_API_KEY environment variable — checked first\n~/.config/telnyx/config.json — fallback (written by telnyx auth setup from the telnyx-cli skill)\n\nTo read from the config file:\n\nAPI_KEY=\"${TELNYX_API_KEY:-$(python3 -c \"import json; print(json.load(open('$HOME/.config/telnyx/config.json'))['api_key'])\" 2>/dev/null || echo '')}\"\n\nIf neither source has a key, hand off to the telnyx-bot-signup skill to generate one. The bot_signup endpoint works for both new and existing accounts — it sends a magic sign-in link to the user's email and produces a fresh API key. If telnyx-bot-signup is not installed:\n\nNo Telnyx API key found. Install the signup skill (clawhub install telnyx-bot-signup) or set the TELNYX_API_KEY environment variable."
      },
      {
        "title": "GitHub Method",
        "body": "Once the GitHub token is ready:\n\nResolve the Telnyx API key (see API Key Resolution above).\nRun {baseDir}/scripts/get-gh-token.sh to extract the GitHub token.\nRun {baseDir}/scripts/evaluate-upgrade.py --github-token <TOKEN> --api-key <API_KEY>\nThe script handles: submission → polling (every 5s, max 120s) → caching → structured output."
      },
      {
        "title": "LinkedIn Method",
        "body": "Resolve the Telnyx API key (see API Key Resolution above).\nRun {baseDir}/scripts/evaluate-upgrade.py --linkedin --api-key <API_KEY>\nThe script outputs an open_url action with the LinkedIn OAuth URL.\nPresent the URL to the user (see notification templates above).\nThe script automatically polls for the evaluation to appear and complete.\nOutput is the same JSON format as the GitHub method."
      },
      {
        "title": "APPROVED",
        "body": "Your Telnyx account has been upgraded to the professional tier! Retrying your request...\n\nThen retry the original blocked operation. If the retry still fails with the same error, the API key needs to be refreshed to pick up professional-tier permissions. Use telnyx-bot-signup to generate a fresh key (same email, sign-in flow) rather than asking the user to visit the portal."
      },
      {
        "title": "REJECTED",
        "body": "Check the used_methods and next_steps fields in the script output:\n\nGitHub only used → Offer LinkedIn:\n\nYour GitHub-based upgrade was not approved. I can try verifying your identity via LinkedIn instead. This requires opening a link in your browser. Want me to proceed?\n\n\n\nLinkedIn only used → Offer GitHub:\n\nYour LinkedIn-based upgrade was not approved. I can try verifying your identity via GitHub instead. Want me to proceed?\n\n\n\nBoth methods used →\n\nYour professional upgrade request was not approved via either verification method.\nPlease contact Telnyx support: https://support.telnyx.com\nThe original task requiring professional features cannot proceed at this time."
      },
      {
        "title": "PASS_TO_HUMAN",
        "body": "Your upgrade application is under manual review by the Telnyx team. A support ticket has been created. I've set up automatic status checks — you'll be notified as soon as a decision is made.\nIn the meantime, freemium features remain available.\n\nSet up a cron job to poll the status automatically. Use the OpenClaw cron system:\n\nopenclaw cron add \\\n  --name \"telnyx-upgrade-poll\" \\\n  --every 3600000 \\\n  --session isolated \\\n  --message \"Run: python3 <SKILL_SCRIPTS_DIR>/evaluate-upgrade.py --poll-only --evaluation-id <EVALUATION_ID> --api-key $TELNYX_API_KEY. If the decision is APPROVED, tell me the account has been upgraded and retry the original blocked operation. If REJECTED, tell me it was not approved and suggest contacting support. If still PASS_TO_HUMAN / under review, do nothing — the next poll will check again.\" \\\n  --announce \\\n  --channel last\n\nReplace <EVALUATION_ID> with the cached evaluation ID and <SKILL_SCRIPTS_DIR> with the absolute path to this skill's scripts directory.\n\nPolling schedule: Every 1 hour (3600000ms). Manual review typically resolves within minutes to hours, so hourly is a good balance between responsiveness and not hammering the API.\n\nOn resolution (APPROVED or REJECTED): The cron job's isolated session will announce the result to the user's last active channel. After announcing, remove the cron job:\n\nopenclaw cron remove <jobId>\n\nThe bot should also update the local cache at ~/.telnyx/upgrade.json and, if APPROVED, retry the original blocked operation.\n\nCleanup: If the cron job runs 24 times (24 hours) with no resolution, it should self-disable and notify the user to contact Telnyx support directly:\n\nYour upgrade application has been under review for over 24 hours. Please contact Telnyx support directly: https://support.telnyx.com"
      },
      {
        "title": "TIMEOUT / POLLING FAILURE",
        "body": "The upgrade evaluation is taking longer than expected. Your evaluation ID is: <EVALUATION_ID>\nI'll check again later. Continuing with freemium features for now.\n\nCache the evaluation_id for later polling."
      },
      {
        "title": "ERROR (API failure)",
        "body": "The upgrade evaluation encountered an error. This may be temporary — I'll retry shortly.\n\nRetry up to 3 times with exponential backoff (1s, 2s, 4s). If still failing, report the error and suggest the user try again later."
      },
      {
        "title": "ALREADY ATTEMPTED",
        "body": "Check used_methods to determine which methods remain:\n\ngithub_oauth used, linkedin_oauth not used →\n\nA GitHub-based upgrade evaluation was already submitted. Each verification method can only be used once. I can try LinkedIn verification instead — this requires opening a link in your browser. Want me to proceed?\n\n\n\nlinkedin_oauth used, github_oauth not used →\n\nA LinkedIn-based upgrade evaluation was already submitted. Each verification method can only be used once. I can try GitHub verification instead. Want me to proceed?\n\n\n\nBoth used →\n\nBoth verification methods (GitHub and LinkedIn) have been used for this account. Please contact Telnyx support: https://support.telnyx.com"
      },
      {
        "title": "Error Handling Reference",
        "body": "#ScenarioDetectionHandling1gh not installedwhich gh failsReport: \"GitHub CLI (gh) is required. Install: https://cli.github.com\". Alternatively, offer manual PAT creation via github.com/settings/tokens.2gh not authenticatedgh auth status failsRun gh auth login --web --scopes user,read:org and guide user through browser flow3ghs_ token (CI/CD)Token prefix = ghs_ABORT with clear message (see Token Type Detection above). Cannot verify human identity. Must gh auth login --web.4github_pat_ tokenToken prefix = github_pat_WARN about degraded data, proceed anyway. Cannot refresh scopes on PATs.5API key invalid/expired401 from gatewayReport to user, suggest checking API key6Already upgraded (prior APPROVED)Cache or status endpoint checkSkip evaluation, proceed with original blocked operation7Attempt limit reached (429)used_methods includes the methodReport that the method was already used. If the other method is available, suggest it. If both used, suggest support.8Network errorsHTTP 0 / connection failureRetry up to 3 times with exponential backoff (1s, 2s, 4s). If persistent, notify user.9Evaluation already in progress (409)Backend returns 409Check cached evaluation_id, resume polling instead of submitting new evaluation10PASS_TO_HUMAN from previous sessionCache shows PASS_TO_HUMANRe-poll the cached evaluation_id silently. Notify user if decision changed.11User doesn't complete device code in timegh auth refresh exits with error after 15 minGenerate new code, re-notify user via their active channel. Max 3 retries before giving up.12User on Telegram, away from machineUser's last channel = telegramSend device code + verification URL to Telegram chat (see templates above)13User on Slack, away from machineUser's last channel = slackSend device code via Slack DM using slack-send.sh (see templates above)14User on phone, NOT logged into GitHubN/A — extra login step on phoneDevice code link still works; user will see GitHub login before device page. One extra tap.15User completely offlineNo channel responds to notificationSave state to ~/.telnyx/upgrade.json with pending_action: \"scope_refresh\". Set up heartbeat polling (every 30 min). On user return, first message = upgrade prompt.16Device code expires (15 min TTL)gh auth refresh exits with errorGenerate new code, re-notify user. Max 3 retries before giving up.17Multiple bots, same userBackend returns 409/429Handle gracefully — check status endpoint, resume polling existing evaluation18GitHub outageAPI calls to GitHub fail with HTTP 5xxDetect via error response. Notify user. Retry later via heartbeat.19User cancels authorizationgh auth refresh returns access_deniedInform user: \"Authorization was cancelled. Run again when ready.\"20Concurrent scope refresh + evaluationRace conditiongh auth refresh is blocking — evaluation only starts after it returns. No race condition."
      }
    ],
    "body": "Telnyx Professional Upgrade Skill\nCompanion Skills\n\nThis skill depends on telnyx-bot-signup for API key generation and refresh. If no Telnyx API key is available, or if the key needs to be refreshed after a successful upgrade, use telnyx-bot-signup to obtain one. The bot_signup endpoint handles both new and existing accounts — just provide the user's email.\n\nSkill\tWhen needed\tInstall\ntelnyx-bot-signup\tNo API key available, or key refresh needed post-upgrade\tclawhub install telnyx-bot-signup\nWhen to Activate\n\nThis skill triggers when the bot encounters a freemium-blocked operation. Activate when ANY of these conditions occur:\n\nAutomatic Triggers (API Error Codes)\nError Code\tContext\tMeaning\n10039\tSMS send\tDestination not verified (freemium restriction)\nD60\tVoice call\tDestination not verified (freemium restriction)\n10038\tVarious\tFeature not available on current plan (porting, short codes, number lookup, SIM, managed accounts, etc.)\nHeuristic Triggers (Capacity Limits)\nPhone number order fails after the first purchase (1 number limit)\nBalance/credit check returns low available credit ($10 ceiling)\nInability to add funds / top up balance — freemium accounts cannot add balance or payment methods. If the bot encounters an error when trying to add funds, check account tier, or top up, and the account is freemium, this is a strong signal that an upgrade is needed.\nAccount shows as \"inactive\" or \"deactivated\" due to $0 balance on freemium tier\nExplicit Triggers\nUser requests an upgrade: \"upgrade my account\", \"I need professional tier\"\nBot needs a non-freemium feature: \"send SMS to unverified number\", \"port a number\", \"create a managed account\"\nUser or bot tries to add balance/payment and is blocked by freemium restrictions\nVerification Methods\n\nTwo verification methods are available. Each can only be used once per account.\n\nMethod\tFlag\tBrowser?\tBest for\nGitHub\t--github-token <TOKEN>\tNo (automated)\tUsers with gh CLI installed\nLinkedIn\t--linkedin\tYes (OAuth consent)\tUsers without GitHub, or after GitHub rejection\nMethod Selection Decision Tree\nWhich method to try?\n├── Check ~/.telnyx/upgrade.json cache\n│   ├── decision: APPROVED → Already upgraded, skip\n│   ├── decision: PASS_TO_HUMAN → Under review, don't retry\n│   └── decision: REJECTED or no cache → Continue\n│\n├── Check used_methods in cache or status endpoint\n│   ├── github_oauth NOT used → Try GitHub first (automated, no browser)\n│   ├── github_oauth used, linkedin_oauth NOT used → Try LinkedIn\n│   └── Both used → Both methods exhausted, contact support\n│\n└── No preference → Try GitHub first (faster, no browser needed)\n\nLinkedIn Verification Method\n\nWhen to use: User has no GitHub account, GitHub method was REJECTED, or user prefers LinkedIn.\n\nFlow:\n\n1. python3 {baseDir}/scripts/evaluate-upgrade.py --linkedin\n   → Returns { action: \"open_url\", url: \"<linkedin_oauth_url>\" }\n\n2. Present the URL to the user:\n   \"To verify your identity, please open this link and sign in with LinkedIn:\n    <url>\n    After authorizing, you can close the browser tab.\"\n\n3. The script polls automatically. When the evaluation completes, it outputs\n   the result JSON (same format as GitHub).\n\n4. Handle outcome: APPROVED / REJECTED / PASS_TO_HUMAN (same as GitHub)\n\n\nNotification templates for LinkedIn URL:\n\nTelegram:\n\n🔗 Telnyx Account Upgrade — LinkedIn Verification\n\nI need to verify your identity via LinkedIn to upgrade your Telnyx account. This is a one-time step.\n\n👉 Open: <URL>\n⏰ Link expires in 10 minutes\n\nSign in with your LinkedIn account when prompted. After authorizing, you can close the tab.\n\n\nSlack:\n\n:link: *Telnyx Account Upgrade — LinkedIn Verification*\n\nI need to verify your identity via LinkedIn to upgrade your Telnyx account. This is a one-time step.\n\n:point_right: <URL|Open LinkedIn Verification>\n:timer_clock: Link expires in 10 minutes\n\nSign in with your LinkedIn account when prompted. After authorizing, you can close the tab.\n\nPre-flight Checks (ALWAYS do these first)\n\nBefore submitting a new evaluation:\n\n1. Check Local Cache\n\nRead ~/.telnyx/upgrade.json. If it exists:\n\ndecision: \"APPROVED\" → Skip evaluation entirely. The account is already upgraded. Retry the blocked operation directly.\ndecision: \"PASS_TO_HUMAN\" → Re-poll the status endpoint with the cached evaluation_id to check if a decision was made. Do NOT submit a new evaluation.\ndecision: \"REJECTED\" → Check used_methods:\nOnly github_oauth used → Try LinkedIn: python3 {baseDir}/scripts/evaluate-upgrade.py --linkedin\nOnly linkedin_oauth used → Try GitHub: python3 {baseDir}/scripts/evaluate-upgrade.py --github-token <TOKEN>\nBoth used → All methods exhausted. Contact support.\nstatus: \"polling_timeout\" → Re-poll the cached evaluation_id. The evaluation may have completed server-side.\n2. Check used_methods via Status Endpoint\n\nIf no cache or cache is stale, poll GET /v2/account/upgrade-request-status/{evaluation_id} (if you have an evaluation_id) or check the latest evaluation. Check which methods have been used and follow the decision tree above.\n\nToken Type Detection and Handling\n\nRun {baseDir}/scripts/check-gh-auth.sh to get token info. Handle based on token_type:\n\nghs_ (GitHub App Installation Token) → ABORT\n\nThese tokens represent a GitHub App, NOT a human user. Cannot verify human identity.\n\nTell the user:\n\nYour GitHub CLI is authenticated with a GitHub App installation token (commonly used in CI/CD environments). This token type cannot access user profile data needed for identity verification.\n\nTo proceed, please authenticate with your personal GitHub account:\n\ngh auth login --web\n\n\nThis will not affect your CI/CD workflows — gh supports multiple accounts.\n\nSTOP — wait for user to re-authenticate, then retry.\n\ngithub_pat_ (Fine-grained PAT) → WARN and PROCEED\n\nFine-grained PATs have limited API access: /user/orgs returns empty, no GraphQL support. Evaluation will have degraded data.\n\nTell the user:\n\nYour GitHub CLI is using a fine-grained personal access token. Some profile data (organizations, GraphQL contributions) may be unavailable, which could affect your evaluation. For best results, run gh auth login --web to use a standard OAuth token.\n\nPROCEED with the token anyway — the evaluator handles partial data.\n\ngho_ or ghp_ (OAuth / Classic PAT) → CHECK SCOPES and PROCEED\n\nThese are compatible token types. Check scopes and refresh if needed.\n\nScope Check and Refresh\n\nRequired scopes: user, read:org\n\nIf check-gh-auth.sh returns missing_scopes that is non-empty:\n\nRun {baseDir}/scripts/refresh-gh-scopes.sh\n\nCheck the output:\n\nsuccess: true → scopes refreshed without browser interaction. Continue to submission.\nrequires_browser: true + success: false → the device_code, verification_uri, and pid fields are returned. Deliver the device code to the user via the Notification Decision Tree below.\n\nAfter the user authorizes, run {baseDir}/scripts/wait-for-auth.sh to confirm the refresh completed:\n\nsuccess: true → scopes refreshed. Continue to submission.\nsuccess: false → device code expired or authorization was denied. Retry from step 1 (max 3 times).\n\nYou can also pass the PID directly: bash {baseDir}/scripts/wait-for-auth.sh --pid <PID>\n\nNotification Decision Tree (Scope Refresh)\n\nWhen the bot needs a scope refresh or token acquisition:\n\nSTART: Bot needs GitHub scope refresh\n│\n├── Is `gh` installed?\n│   ├── NO → Notify user: \"Install gh: https://cli.github.com\"\n│   │        OR offer manual PAT creation via github.com/settings/tokens\n│   │        INTERVENTION: MEDIUM\n│   │\n│   └── YES → Check token type (prefix)\n│       │\n│       ├── ghs_ (installation) → ABORT\n│       │   Notify user: \"Need personal GitHub auth, not CI/CD token\"\n│       │   INTERVENTION: MEDIUM\n│       │\n│       ├── github_pat_ (fine-grained) → WARN, proceed with degraded data\n│       │   Cannot refresh scopes on PATs → proceed as-is\n│       │   INTERVENTION: ZERO (but evaluation has less data)\n│       │\n│       └── gho_ / ghp_ (OAuth / classic PAT) → Check scopes\n│           │\n│           ├── Scopes OK → PROCEED directly to upgrade evaluation\n│           │   INTERVENTION: ZERO\n│           │\n│           └── Scopes missing → Need refresh\n│               │\n│               └── Send device code to user's active channel\n│                   │\n│                   ├── User reachable on Telegram/Slack/etc?\n│                   │   ├── YES → Send code + link (see Cross-Channel Notification)\n│                   │   │   INTERVENTION: MINIMAL (user taps link, enters code)\n│                   │   │\n│                   │   └── NO (offline) → Save state + heartbeat\n│                   │       INTERVENTION: DEFERRED\n\nCross-Channel Notification (Minimal Intervention)\n\nParse the device code from refresh-gh-scopes.sh output (device_code and verification_uri fields).\n\nSend to the user's active channel:\n\nTelegram:\n\n🔑 Telnyx Account Upgrade\n\nI need to verify your GitHub identity to upgrade your Telnyx account from freemium to professional tier. This is a one-time step.\n\n👉 Visit: https://github.com/login/device\n📝 Enter code: <DEVICE_CODE>\n⏰ Expires in 15 minutes\n\nTap the link above to open in your browser. You must be logged into GitHub.\n\n\nSlack:\n\n:key: *Telnyx Account Upgrade*\n\nI need to verify your GitHub identity to upgrade your Telnyx account. This is a one-time step.\n\n:point_right: <https://github.com/login/device|Open GitHub Device Authorization>\n:pencil: Enter code: `<DEVICE_CODE>`\n:timer_clock: Expires in 15 minutes\n\nYou must be logged into GitHub in your browser.\n\n\nSMS (last resort):\n\nTelnyx upgrade: enter code <DEVICE_CODE> at github.com/login/device within 15 min. Must be logged into GitHub.\n\n\nUse the user's last active channel (check OpenClaw config at ~/.openclaw/openclaw.json). Priority: Telegram > Slack > SMS.\n\nDeferred (User Offline)\n\nIf the user is unreachable:\n\nSave state to ~/.telnyx/upgrade.json:\n\n{\n  \"pending_action\": \"scope_refresh\",\n  \"reason\": \"missing_scopes\",\n  \"required_scopes\": [\"user\", \"read:org\"],\n  \"queued_at\": \"<ISO_TIMESTAMP>\",\n  \"original_task\": \"<description of what triggered the upgrade>\"\n}\n\n\nOn user return (next message to bot), respond:\n\nBefore we continue, I need to upgrade your Telnyx account to use [requested feature]. This requires a one-time GitHub verification. Ready to proceed?\n\nProactive Upgrade (Optional)\n\nOn first Telnyx API interaction or skill load, the bot MAY proactively check the account tier:\n\nIf freemium and no prior attempt:\nIf gho_ token with user scope already present → start upgrade silently in background. Notify user only on completion.\nIf scopes missing but token compatible → offer: \"I notice you're on Telnyx's freemium tier. Some features you might need require an upgrade. I can handle this now (takes ~2 min, needs GitHub verification) or we can do it later when you actually need it. Want me to proceed?\"\nIf gh not installed or ghs_ token → queue for later, don't interrupt.\nIf prior APPROVED → no action needed.\nIf prior REJECTED → inform only when user hits a freemium wall.\nIf prior PASS_TO_HUMAN → re-poll silently.\nIntent Analysis (Before API Call)\n\nThe bot can analyze the user's intent before making a Telnyx API call to proactively trigger the upgrade:\n\nUser says\tBot infers\tAction\n\"Send SMS to +1-555-123-4567\"\tWill need non-freemium (unverified destination)\tCheck tier → pre-upgrade if needed\n\"Port my number from AT&T\"\tWill need non-freemium (porting blocked)\tCheck tier → pre-upgrade if needed\n\"Buy 5 phone numbers\"\tWill need non-freemium (1 number limit)\tCheck tier → pre-upgrade if needed\n\"Set up a SIP trunk\"\tWill need non-freemium (SIM/SIP blocked)\tCheck tier → pre-upgrade if needed\n\"Create a managed account\"\tWill need non-freemium (10038)\tCheck tier → pre-upgrade if needed\n\"Check my balance\"\tFreemium OK\tNo action\n\"Buy a phone number\"\tFreemium OK (1st number)\tNo action\nAPI Key Resolution\n\nThe Telnyx API key is resolved in this order:\n\nTELNYX_API_KEY environment variable — checked first\n~/.config/telnyx/config.json — fallback (written by telnyx auth setup from the telnyx-cli skill)\n\nTo read from the config file:\n\nAPI_KEY=\"${TELNYX_API_KEY:-$(python3 -c \"import json; print(json.load(open('$HOME/.config/telnyx/config.json'))['api_key'])\" 2>/dev/null || echo '')}\"\n\n\nIf neither source has a key, hand off to the telnyx-bot-signup skill to generate one. The bot_signup endpoint works for both new and existing accounts — it sends a magic sign-in link to the user's email and produces a fresh API key. If telnyx-bot-signup is not installed:\n\nNo Telnyx API key found. Install the signup skill (clawhub install telnyx-bot-signup) or set the TELNYX_API_KEY environment variable.\n\nSubmission and Polling\nGitHub Method\n\nOnce the GitHub token is ready:\n\nResolve the Telnyx API key (see API Key Resolution above).\nRun {baseDir}/scripts/get-gh-token.sh to extract the GitHub token.\nRun {baseDir}/scripts/evaluate-upgrade.py --github-token <TOKEN> --api-key <API_KEY>\nThe script handles: submission → polling (every 5s, max 120s) → caching → structured output.\nLinkedIn Method\nResolve the Telnyx API key (see API Key Resolution above).\nRun {baseDir}/scripts/evaluate-upgrade.py --linkedin --api-key <API_KEY>\nThe script outputs an open_url action with the LinkedIn OAuth URL.\nPresent the URL to the user (see notification templates above).\nThe script automatically polls for the evaluation to appear and complete.\nOutput is the same JSON format as the GitHub method.\nResponse Templates (Per Outcome)\nAPPROVED\n\nYour Telnyx account has been upgraded to the professional tier! Retrying your request...\n\nThen retry the original blocked operation. If the retry still fails with the same error, the API key needs to be refreshed to pick up professional-tier permissions. Use telnyx-bot-signup to generate a fresh key (same email, sign-in flow) rather than asking the user to visit the portal.\n\nREJECTED\n\nCheck the used_methods and next_steps fields in the script output:\n\nGitHub only used → Offer LinkedIn:\n\nYour GitHub-based upgrade was not approved. I can try verifying your identity via LinkedIn instead. This requires opening a link in your browser. Want me to proceed?\n\nLinkedIn only used → Offer GitHub:\n\nYour LinkedIn-based upgrade was not approved. I can try verifying your identity via GitHub instead. Want me to proceed?\n\nBoth methods used →\n\nYour professional upgrade request was not approved via either verification method.\n\nPlease contact Telnyx support: https://support.telnyx.com\n\nThe original task requiring professional features cannot proceed at this time.\n\nPASS_TO_HUMAN\n\nYour upgrade application is under manual review by the Telnyx team. A support ticket has been created. I've set up automatic status checks — you'll be notified as soon as a decision is made.\n\nIn the meantime, freemium features remain available.\n\nSet up a cron job to poll the status automatically. Use the OpenClaw cron system:\n\nopenclaw cron add \\\n  --name \"telnyx-upgrade-poll\" \\\n  --every 3600000 \\\n  --session isolated \\\n  --message \"Run: python3 <SKILL_SCRIPTS_DIR>/evaluate-upgrade.py --poll-only --evaluation-id <EVALUATION_ID> --api-key $TELNYX_API_KEY. If the decision is APPROVED, tell me the account has been upgraded and retry the original blocked operation. If REJECTED, tell me it was not approved and suggest contacting support. If still PASS_TO_HUMAN / under review, do nothing — the next poll will check again.\" \\\n  --announce \\\n  --channel last\n\n\nReplace <EVALUATION_ID> with the cached evaluation ID and <SKILL_SCRIPTS_DIR> with the absolute path to this skill's scripts directory.\n\nPolling schedule: Every 1 hour (3600000ms). Manual review typically resolves within minutes to hours, so hourly is a good balance between responsiveness and not hammering the API.\n\nOn resolution (APPROVED or REJECTED): The cron job's isolated session will announce the result to the user's last active channel. After announcing, remove the cron job:\n\nopenclaw cron remove <jobId>\n\n\nThe bot should also update the local cache at ~/.telnyx/upgrade.json and, if APPROVED, retry the original blocked operation.\n\nCleanup: If the cron job runs 24 times (24 hours) with no resolution, it should self-disable and notify the user to contact Telnyx support directly:\n\nYour upgrade application has been under review for over 24 hours. Please contact Telnyx support directly: https://support.telnyx.com\n\nTIMEOUT / POLLING FAILURE\n\nThe upgrade evaluation is taking longer than expected. Your evaluation ID is: <EVALUATION_ID>\n\nI'll check again later. Continuing with freemium features for now.\n\nCache the evaluation_id for later polling.\n\nERROR (API failure)\n\nThe upgrade evaluation encountered an error. This may be temporary — I'll retry shortly.\n\nRetry up to 3 times with exponential backoff (1s, 2s, 4s). If still failing, report the error and suggest the user try again later.\n\nALREADY ATTEMPTED\n\nCheck used_methods to determine which methods remain:\n\ngithub_oauth used, linkedin_oauth not used →\n\nA GitHub-based upgrade evaluation was already submitted. Each verification method can only be used once. I can try LinkedIn verification instead — this requires opening a link in your browser. Want me to proceed?\n\nlinkedin_oauth used, github_oauth not used →\n\nA LinkedIn-based upgrade evaluation was already submitted. Each verification method can only be used once. I can try GitHub verification instead. Want me to proceed?\n\nBoth used →\n\nBoth verification methods (GitHub and LinkedIn) have been used for this account. Please contact Telnyx support: https://support.telnyx.com\n\nError Handling Reference\n#\tScenario\tDetection\tHandling\n1\tgh not installed\twhich gh fails\tReport: \"GitHub CLI (gh) is required. Install: https://cli.github.com\". Alternatively, offer manual PAT creation via github.com/settings/tokens.\n2\tgh not authenticated\tgh auth status fails\tRun gh auth login --web --scopes user,read:org and guide user through browser flow\n3\tghs_ token (CI/CD)\tToken prefix = ghs_\tABORT with clear message (see Token Type Detection above). Cannot verify human identity. Must gh auth login --web.\n4\tgithub_pat_ token\tToken prefix = github_pat_\tWARN about degraded data, proceed anyway. Cannot refresh scopes on PATs.\n5\tAPI key invalid/expired\t401 from gateway\tReport to user, suggest checking API key\n6\tAlready upgraded (prior APPROVED)\tCache or status endpoint check\tSkip evaluation, proceed with original blocked operation\n7\tAttempt limit reached (429)\tused_methods includes the method\tReport that the method was already used. If the other method is available, suggest it. If both used, suggest support.\n8\tNetwork errors\tHTTP 0 / connection failure\tRetry up to 3 times with exponential backoff (1s, 2s, 4s). If persistent, notify user.\n9\tEvaluation already in progress (409)\tBackend returns 409\tCheck cached evaluation_id, resume polling instead of submitting new evaluation\n10\tPASS_TO_HUMAN from previous session\tCache shows PASS_TO_HUMAN\tRe-poll the cached evaluation_id silently. Notify user if decision changed.\n11\tUser doesn't complete device code in time\tgh auth refresh exits with error after 15 min\tGenerate new code, re-notify user via their active channel. Max 3 retries before giving up.\n12\tUser on Telegram, away from machine\tUser's last channel = telegram\tSend device code + verification URL to Telegram chat (see templates above)\n13\tUser on Slack, away from machine\tUser's last channel = slack\tSend device code via Slack DM using slack-send.sh (see templates above)\n14\tUser on phone, NOT logged into GitHub\tN/A — extra login step on phone\tDevice code link still works; user will see GitHub login before device page. One extra tap.\n15\tUser completely offline\tNo channel responds to notification\tSave state to ~/.telnyx/upgrade.json with pending_action: \"scope_refresh\". Set up heartbeat polling (every 30 min). On user return, first message = upgrade prompt.\n16\tDevice code expires (15 min TTL)\tgh auth refresh exits with error\tGenerate new code, re-notify user. Max 3 retries before giving up.\n17\tMultiple bots, same user\tBackend returns 409/429\tHandle gracefully — check status endpoint, resume polling existing evaluation\n18\tGitHub outage\tAPI calls to GitHub fail with HTTP 5xx\tDetect via error response. Notify user. Retry later via heartbeat.\n19\tUser cancels authorization\tgh auth refresh returns access_denied\tInform user: \"Authorization was cancelled. Run again when ready.\"\n20\tConcurrent scope refresh + evaluation\tRace condition\tgh auth refresh is blocking — evaluation only starts after it returns. No race condition."
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/teamtelnyx/telnyx-freemium-upgrade",
    "publisherUrl": "https://clawhub.ai/teamtelnyx/telnyx-freemium-upgrade",
    "owner": "teamtelnyx",
    "version": "1.0.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/telnyx-freemium-upgrade",
    "downloadUrl": "https://openagent3.xyz/downloads/telnyx-freemium-upgrade",
    "agentUrl": "https://openagent3.xyz/skills/telnyx-freemium-upgrade/agent",
    "manifestUrl": "https://openagent3.xyz/skills/telnyx-freemium-upgrade/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/telnyx-freemium-upgrade/agent.md"
  }
}