{
  "schemaVersion": "1.0",
  "item": {
    "slug": "doubleword-api",
    "name": "Doubleword API",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/pjb157/doubleword-api",
    "canonicalUrl": "https://clawhub.ai/pjb157/doubleword-api",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/doubleword-api",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=doubleword-api",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "SKILL.md",
      "scripts/create_batch_file.py",
      "references/api_reference.md"
    ],
    "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-04-30T16:55:25.780Z",
      "expiresAt": "2026-05-07T16:55:25.780Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
        "contentDisposition": "attachment; filename=\"network-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/doubleword-api"
    },
    "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/doubleword-api",
    "agentPageUrl": "https://openagent3.xyz/skills/doubleword-api/agent",
    "manifestUrl": "https://openagent3.xyz/skills/doubleword-api/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/doubleword-api/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": "Doubleword Batch Inference",
        "body": "Process multiple AI inference requests asynchronously using the Doubleword batch API."
      },
      {
        "title": "When to Use Batches",
        "body": "Batches are ideal for:\n\nMultiple independent requests that can run simultaneously\nWorkloads that don't require immediate responses\nLarge volumes that would exceed rate limits if sent individually\nCost-sensitive workloads (24h window offers better pricing)"
      },
      {
        "title": "Quick Start",
        "body": "Basic workflow for any batch job:\n\nCreate JSONL file with requests (one JSON object per line)\nUpload file to get file ID\nCreate batch using file ID\nPoll status until complete\nDownload results from output_file_id"
      },
      {
        "title": "Step 1: Create Batch Request File",
        "body": "Create a .jsonl file where each line contains a single request:\n\n{\"custom_id\": \"req-1\", \"method\": \"POST\", \"url\": \"/v1/chat/completions\", \"body\": {\"model\": \"anthropic/claude-3-5-sonnet\", \"messages\": [{\"role\": \"user\", \"content\": \"What is 2+2?\"}]}}\n{\"custom_id\": \"req-2\", \"method\": \"POST\", \"url\": \"/v1/chat/completions\", \"body\": {\"model\": \"anthropic/claude-3-5-sonnet\", \"messages\": [{\"role\": \"user\", \"content\": \"What is the capital of France?\"}]}}\n\nRequired fields per line:\n\ncustom_id: Unique identifier (max 64 chars) - use descriptive IDs like \"user-123-question-5\" for easier result mapping\nmethod: Always \"POST\"\nurl: Always \"/v1/chat/completions\"\nbody: Standard API request with model and messages\n\nOptional body parameters:\n\ntemperature: 0-2 (default: 1.0)\nmax_tokens: Maximum response tokens\ntop_p: Nucleus sampling parameter\nstop: Stop sequences\n\nFile limits:\n\nMax size: 200MB\nFormat: JSONL only (JSON Lines - newline-delimited JSON)\nSplit large batches into multiple files if needed\n\nHelper script:\nUse scripts/create_batch_file.py to generate JSONL files programmatically:\n\npython scripts/create_batch_file.py output.jsonl\n\nModify the script's requests list to generate your specific batch requests."
      },
      {
        "title": "Step 2: Upload File",
        "body": "Upload the JSONL file:\n\ncurl https://api.doubleword.ai/v1/files \\\n  -H \"Authorization: Bearer $DOUBLEWORD_API_KEY\" \\\n  -F purpose=\"batch\" \\\n  -F file=\"@batch_requests.jsonl\"\n\nResponse contains id field - save this file ID for next step."
      },
      {
        "title": "Step 3: Create Batch",
        "body": "Create the batch job using the file ID:\n\ncurl https://api.doubleword.ai/v1/batches \\\n  -H \"Authorization: Bearer $DOUBLEWORD_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"input_file_id\": \"file-abc123\",\n    \"endpoint\": \"/v1/chat/completions\",\n    \"completion_window\": \"24h\"\n  }'\n\nParameters:\n\ninput_file_id: File ID from upload step\nendpoint: Always \"/v1/chat/completions\"\ncompletion_window: Choose \"24h\" (better pricing) or \"1h\" (50% premium, faster results)\n\nResponse contains batch id - save this for status polling."
      },
      {
        "title": "Step 4: Poll Status",
        "body": "Check batch progress:\n\ncurl https://api.doubleword.ai/v1/batches/batch-xyz789 \\\n  -H \"Authorization: Bearer $DOUBLEWORD_API_KEY\"\n\nStatus progression:\n\nvalidating - Checking input file format\nin_progress - Processing requests\ncompleted - All requests finished\n\nOther statuses:\n\nfailed - Batch failed (check error_file_id)\nexpired - Batch timed out\ncancelling/cancelled - Batch cancelled\n\nResponse includes:\n\noutput_file_id - Download results here\nerror_file_id - Failed requests (if any)\nrequest_counts - Total/completed/failed counts\n\nPolling frequency: Check every 30-60 seconds during processing.\n\nEarly access: Results available via output_file_id before batch fully completes - check X-Incomplete header."
      },
      {
        "title": "Step 5: Download Results",
        "body": "Download completed results:\n\ncurl https://api.doubleword.ai/v1/files/file-output123/content \\\n  -H \"Authorization: Bearer $DOUBLEWORD_API_KEY\" \\\n  > results.jsonl\n\nResponse headers:\n\nX-Incomplete: true - Batch still processing, more results coming\nX-Last-Line: 45 - Resume point for partial downloads\n\nOutput format (each line):\n\n{\n  \"id\": \"batch-req-abc\",\n  \"custom_id\": \"request-1\",\n  \"response\": {\n    \"status_code\": 200,\n    \"body\": {\n      \"id\": \"chatcmpl-xyz\",\n      \"choices\": [{\n        \"message\": {\n          \"role\": \"assistant\",\n          \"content\": \"The answer is 4.\"\n        }\n      }]\n    }\n  }\n}\n\nDownload errors (if any):\n\ncurl https://api.doubleword.ai/v1/files/file-error123/content \\\n  -H \"Authorization: Bearer $DOUBLEWORD_API_KEY\" \\\n  > errors.jsonl\n\nError format (each line):\n\n{\n  \"id\": \"batch-req-def\",\n  \"custom_id\": \"request-2\",\n  \"error\": {\n    \"code\": \"invalid_request\",\n    \"message\": \"Missing required parameter\"\n  }\n}"
      },
      {
        "title": "List All Batches",
        "body": "curl https://api.doubleword.ai/v1/batches?limit=10 \\\n  -H \"Authorization: Bearer $DOUBLEWORD_API_KEY\""
      },
      {
        "title": "Cancel Batch",
        "body": "curl https://api.doubleword.ai/v1/batches/batch-xyz789/cancel \\\n  -X POST \\\n  -H \"Authorization: Bearer $DOUBLEWORD_API_KEY\"\n\nNotes:\n\nUnprocessed requests are cancelled\nAlready-processed results remain downloadable\nCannot cancel completed batches"
      },
      {
        "title": "Processing Results",
        "body": "Parse JSONL output line-by-line:\n\nimport json\n\nwith open('results.jsonl') as f:\n    for line in f:\n        result = json.loads(line)\n        custom_id = result['custom_id']\n        content = result['response']['body']['choices'][0]['message']['content']\n        print(f\"{custom_id}: {content}\")"
      },
      {
        "title": "Handling Partial Results",
        "body": "Check for incomplete batches and resume:\n\nimport requests\n\nresponse = requests.get(\n    'https://api.doubleword.ai/v1/files/file-output123/content',\n    headers={'Authorization': f'Bearer {api_key}'}\n)\n\nif response.headers.get('X-Incomplete') == 'true':\n    last_line = int(response.headers.get('X-Last-Line', 0))\n    print(f\"Batch incomplete. Processed {last_line} requests so far.\")\n    # Continue polling and download again later"
      },
      {
        "title": "Retry Failed Requests",
        "body": "Extract failed requests from error file and resubmit:\n\nimport json\n\nfailed_ids = []\nwith open('errors.jsonl') as f:\n    for line in f:\n        error = json.loads(line)\n        failed_ids.append(error['custom_id'])\n\nprint(f\"Failed requests: {failed_ids}\")\n# Create new batch with only failed requests"
      },
      {
        "title": "Best Practices",
        "body": "Descriptive custom_ids: Include context in IDs for easier result mapping\n\nGood: \"user-123-question-5\"\nBad: \"1\", \"req1\"\n\n\n\nValidate JSONL locally: Ensure each line is valid JSON before upload\n\n\nSplit large files: Keep under 200MB limit\n\n\nChoose appropriate window: Use 24h for cost savings, 1h only when time-sensitive\n\n\nHandle errors gracefully: Always check error_file_id and retry failed requests\n\n\nMonitor request_counts: Track progress via completed/total ratio\n\n\nSave file IDs: Store batch_id, input_file_id, output_file_id for later retrieval"
      },
      {
        "title": "Reference Documentation",
        "body": "For complete API details including authentication, rate limits, and advanced parameters, see:\n\nAPI Reference: references/api_reference.md - Full endpoint documentation and schemas"
      }
    ],
    "body": "Doubleword Batch Inference\n\nProcess multiple AI inference requests asynchronously using the Doubleword batch API.\n\nWhen to Use Batches\n\nBatches are ideal for:\n\nMultiple independent requests that can run simultaneously\nWorkloads that don't require immediate responses\nLarge volumes that would exceed rate limits if sent individually\nCost-sensitive workloads (24h window offers better pricing)\nQuick Start\n\nBasic workflow for any batch job:\n\nCreate JSONL file with requests (one JSON object per line)\nUpload file to get file ID\nCreate batch using file ID\nPoll status until complete\nDownload results from output_file_id\nWorkflow\nStep 1: Create Batch Request File\n\nCreate a .jsonl file where each line contains a single request:\n\n{\"custom_id\": \"req-1\", \"method\": \"POST\", \"url\": \"/v1/chat/completions\", \"body\": {\"model\": \"anthropic/claude-3-5-sonnet\", \"messages\": [{\"role\": \"user\", \"content\": \"What is 2+2?\"}]}}\n{\"custom_id\": \"req-2\", \"method\": \"POST\", \"url\": \"/v1/chat/completions\", \"body\": {\"model\": \"anthropic/claude-3-5-sonnet\", \"messages\": [{\"role\": \"user\", \"content\": \"What is the capital of France?\"}]}}\n\n\nRequired fields per line:\n\ncustom_id: Unique identifier (max 64 chars) - use descriptive IDs like \"user-123-question-5\" for easier result mapping\nmethod: Always \"POST\"\nurl: Always \"/v1/chat/completions\"\nbody: Standard API request with model and messages\n\nOptional body parameters:\n\ntemperature: 0-2 (default: 1.0)\nmax_tokens: Maximum response tokens\ntop_p: Nucleus sampling parameter\nstop: Stop sequences\n\nFile limits:\n\nMax size: 200MB\nFormat: JSONL only (JSON Lines - newline-delimited JSON)\nSplit large batches into multiple files if needed\n\nHelper script: Use scripts/create_batch_file.py to generate JSONL files programmatically:\n\npython scripts/create_batch_file.py output.jsonl\n\n\nModify the script's requests list to generate your specific batch requests.\n\nStep 2: Upload File\n\nUpload the JSONL file:\n\ncurl https://api.doubleword.ai/v1/files \\\n  -H \"Authorization: Bearer $DOUBLEWORD_API_KEY\" \\\n  -F purpose=\"batch\" \\\n  -F file=\"@batch_requests.jsonl\"\n\n\nResponse contains id field - save this file ID for next step.\n\nStep 3: Create Batch\n\nCreate the batch job using the file ID:\n\ncurl https://api.doubleword.ai/v1/batches \\\n  -H \"Authorization: Bearer $DOUBLEWORD_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"input_file_id\": \"file-abc123\",\n    \"endpoint\": \"/v1/chat/completions\",\n    \"completion_window\": \"24h\"\n  }'\n\n\nParameters:\n\ninput_file_id: File ID from upload step\nendpoint: Always \"/v1/chat/completions\"\ncompletion_window: Choose \"24h\" (better pricing) or \"1h\" (50% premium, faster results)\n\nResponse contains batch id - save this for status polling.\n\nStep 4: Poll Status\n\nCheck batch progress:\n\ncurl https://api.doubleword.ai/v1/batches/batch-xyz789 \\\n  -H \"Authorization: Bearer $DOUBLEWORD_API_KEY\"\n\n\nStatus progression:\n\nvalidating - Checking input file format\nin_progress - Processing requests\ncompleted - All requests finished\n\nOther statuses:\n\nfailed - Batch failed (check error_file_id)\nexpired - Batch timed out\ncancelling/cancelled - Batch cancelled\n\nResponse includes:\n\noutput_file_id - Download results here\nerror_file_id - Failed requests (if any)\nrequest_counts - Total/completed/failed counts\n\nPolling frequency: Check every 30-60 seconds during processing.\n\nEarly access: Results available via output_file_id before batch fully completes - check X-Incomplete header.\n\nStep 5: Download Results\n\nDownload completed results:\n\ncurl https://api.doubleword.ai/v1/files/file-output123/content \\\n  -H \"Authorization: Bearer $DOUBLEWORD_API_KEY\" \\\n  > results.jsonl\n\n\nResponse headers:\n\nX-Incomplete: true - Batch still processing, more results coming\nX-Last-Line: 45 - Resume point for partial downloads\n\nOutput format (each line):\n\n{\n  \"id\": \"batch-req-abc\",\n  \"custom_id\": \"request-1\",\n  \"response\": {\n    \"status_code\": 200,\n    \"body\": {\n      \"id\": \"chatcmpl-xyz\",\n      \"choices\": [{\n        \"message\": {\n          \"role\": \"assistant\",\n          \"content\": \"The answer is 4.\"\n        }\n      }]\n    }\n  }\n}\n\n\nDownload errors (if any):\n\ncurl https://api.doubleword.ai/v1/files/file-error123/content \\\n  -H \"Authorization: Bearer $DOUBLEWORD_API_KEY\" \\\n  > errors.jsonl\n\n\nError format (each line):\n\n{\n  \"id\": \"batch-req-def\",\n  \"custom_id\": \"request-2\",\n  \"error\": {\n    \"code\": \"invalid_request\",\n    \"message\": \"Missing required parameter\"\n  }\n}\n\nAdditional Operations\nList All Batches\ncurl https://api.doubleword.ai/v1/batches?limit=10 \\\n  -H \"Authorization: Bearer $DOUBLEWORD_API_KEY\"\n\nCancel Batch\ncurl https://api.doubleword.ai/v1/batches/batch-xyz789/cancel \\\n  -X POST \\\n  -H \"Authorization: Bearer $DOUBLEWORD_API_KEY\"\n\n\nNotes:\n\nUnprocessed requests are cancelled\nAlready-processed results remain downloadable\nCannot cancel completed batches\nCommon Patterns\nProcessing Results\n\nParse JSONL output line-by-line:\n\nimport json\n\nwith open('results.jsonl') as f:\n    for line in f:\n        result = json.loads(line)\n        custom_id = result['custom_id']\n        content = result['response']['body']['choices'][0]['message']['content']\n        print(f\"{custom_id}: {content}\")\n\nHandling Partial Results\n\nCheck for incomplete batches and resume:\n\nimport requests\n\nresponse = requests.get(\n    'https://api.doubleword.ai/v1/files/file-output123/content',\n    headers={'Authorization': f'Bearer {api_key}'}\n)\n\nif response.headers.get('X-Incomplete') == 'true':\n    last_line = int(response.headers.get('X-Last-Line', 0))\n    print(f\"Batch incomplete. Processed {last_line} requests so far.\")\n    # Continue polling and download again later\n\nRetry Failed Requests\n\nExtract failed requests from error file and resubmit:\n\nimport json\n\nfailed_ids = []\nwith open('errors.jsonl') as f:\n    for line in f:\n        error = json.loads(line)\n        failed_ids.append(error['custom_id'])\n\nprint(f\"Failed requests: {failed_ids}\")\n# Create new batch with only failed requests\n\nBest Practices\n\nDescriptive custom_ids: Include context in IDs for easier result mapping\n\nGood: \"user-123-question-5\"\nBad: \"1\", \"req1\"\n\nValidate JSONL locally: Ensure each line is valid JSON before upload\n\nSplit large files: Keep under 200MB limit\n\nChoose appropriate window: Use 24h for cost savings, 1h only when time-sensitive\n\nHandle errors gracefully: Always check error_file_id and retry failed requests\n\nMonitor request_counts: Track progress via completed/total ratio\n\nSave file IDs: Store batch_id, input_file_id, output_file_id for later retrieval\n\nReference Documentation\n\nFor complete API details including authentication, rate limits, and advanced parameters, see:\n\nAPI Reference: references/api_reference.md - Full endpoint documentation and schemas"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/pjb157/doubleword-api",
    "publisherUrl": "https://clawhub.ai/pjb157/doubleword-api",
    "owner": "pjb157",
    "version": "1.0.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/doubleword-api",
    "downloadUrl": "https://openagent3.xyz/downloads/doubleword-api",
    "agentUrl": "https://openagent3.xyz/skills/doubleword-api/agent",
    "manifestUrl": "https://openagent3.xyz/skills/doubleword-api/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/doubleword-api/agent.md"
  }
}