{
  "schemaVersion": "1.0",
  "item": {
    "slug": "coda-api",
    "name": "Coda",
    "source": "tencent",
    "type": "skill",
    "category": "效率提升",
    "sourceUrl": "https://clawhub.ai/byungkyu/coda-api",
    "canonicalUrl": "https://clawhub.ai/byungkyu/coda-api",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/coda-api",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=coda-api",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "SKILL.md",
      "LICENSE.txt"
    ],
    "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",
      "slug": "coda-api",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-29T12:13:06.037Z",
      "expiresAt": "2026-05-06T12:13:06.037Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=coda-api",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=coda-api",
        "contentDisposition": "attachment; filename=\"coda-api-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null,
        "slug": "coda-api"
      },
      "scope": "item",
      "summary": "Item download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this item.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/coda-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/coda-api",
    "agentPageUrl": "https://openagent3.xyz/skills/coda-api/agent",
    "manifestUrl": "https://openagent3.xyz/skills/coda-api/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/coda-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": "Coda",
        "body": "Access the Coda API with managed OAuth authentication. Manage docs, pages, tables, rows, formulas, and controls with full CRUD operations."
      },
      {
        "title": "Quick Start",
        "body": "# List your docs\npython <<'EOF'\nimport urllib.request, os, json\nreq = urllib.request.Request('https://gateway.maton.ai/coda/apis/v1/docs')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF"
      },
      {
        "title": "Base URL",
        "body": "https://gateway.maton.ai/coda/apis/v1/{resource}\n\nReplace {resource} with the actual Coda API endpoint path. The gateway proxies requests to coda.io/apis/v1 and automatically injects your OAuth token."
      },
      {
        "title": "Authentication",
        "body": "All requests require the Maton API key in the Authorization header:\n\nAuthorization: Bearer $MATON_API_KEY\n\nEnvironment Variable: Set your API key as MATON_API_KEY:\n\nexport MATON_API_KEY=\"YOUR_API_KEY\""
      },
      {
        "title": "Getting Your API Key",
        "body": "Sign in or create an account at maton.ai\nGo to maton.ai/settings\nCopy your API key"
      },
      {
        "title": "Connection Management",
        "body": "Manage your Coda OAuth connections at https://ctrl.maton.ai."
      },
      {
        "title": "List Connections",
        "body": "python <<'EOF'\nimport urllib.request, os, json\nreq = urllib.request.Request('https://ctrl.maton.ai/connections?app=coda&status=ACTIVE')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF"
      },
      {
        "title": "Create Connection",
        "body": "python <<'EOF'\nimport urllib.request, os, json\ndata = json.dumps({'app': 'coda'}).encode()\nreq = urllib.request.Request('https://ctrl.maton.ai/connections', data=data, method='POST')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nreq.add_header('Content-Type', 'application/json')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF"
      },
      {
        "title": "Get Connection",
        "body": "python <<'EOF'\nimport urllib.request, os, json\nreq = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF\n\nResponse:\n\n{\n  \"connection\": {\n    \"connection_id\": \"f46d34b1-3735-478a-a0d7-54115a16cd46\",\n    \"status\": \"ACTIVE\",\n    \"creation_time\": \"2026-02-12T01:38:10.500238Z\",\n    \"last_updated_time\": \"2026-02-12T01:38:33.545353Z\",\n    \"url\": \"https://connect.maton.ai/?session_token=...\",\n    \"app\": \"coda\",\n    \"metadata\": {}\n  }\n}\n\nOpen the returned url in a browser to complete OAuth authorization."
      },
      {
        "title": "Delete Connection",
        "body": "python <<'EOF'\nimport urllib.request, os, json\nreq = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}', method='DELETE')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF"
      },
      {
        "title": "Specifying Connection",
        "body": "If you have multiple Coda connections, specify which one to use with the Maton-Connection header:\n\npython <<'EOF'\nimport urllib.request, os, json\nreq = urllib.request.Request('https://gateway.maton.ai/coda/apis/v1/docs')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nreq.add_header('Maton-Connection', 'f46d34b1-3735-478a-a0d7-54115a16cd46')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF\n\nIf omitted, the gateway uses the default (oldest) active connection."
      },
      {
        "title": "Account",
        "body": "Get Current User\n\nGET /coda/apis/v1/whoami\n\nReturns information about the authenticated user."
      },
      {
        "title": "Docs",
        "body": "List Docs\n\nGET /coda/apis/v1/docs\n\nQuery parameters:\n\nisOwner - Show only owned docs (true/false)\nquery - Search query\nsourceDoc - Filter by source doc ID\nisStarred - Show only starred docs\ninGallery - Show only gallery docs\nworkspaceId - Filter by workspace\nfolderId - Filter by folder\nlimit - Page size (default: 25, max: 200)\npageToken - Pagination token\n\nCreate Doc\n\nPOST /coda/apis/v1/docs\nContent-Type: application/json\n\n{\n  \"title\": \"My New Doc\",\n  \"sourceDoc\": \"optional-source-doc-id\",\n  \"timezone\": \"America/Los_Angeles\",\n  \"folderId\": \"optional-folder-id\"\n}\n\nGet Doc\n\nGET /coda/apis/v1/docs/{docId}\n\nDelete Doc\n\nDELETE /coda/apis/v1/docs/{docId}"
      },
      {
        "title": "Pages",
        "body": "List Pages\n\nGET /coda/apis/v1/docs/{docId}/pages\n\nQuery parameters:\n\nlimit - Page size\npageToken - Pagination token\n\nCreate Page\n\nPOST /coda/apis/v1/docs/{docId}/pages\nContent-Type: application/json\n\n{\n  \"name\": \"New Page\",\n  \"subtitle\": \"Optional subtitle\",\n  \"parentPageId\": \"optional-parent-page-id\"\n}\n\nGet Page\n\nGET /coda/apis/v1/docs/{docId}/pages/{pageIdOrName}\n\nUpdate Page\n\nPUT /coda/apis/v1/docs/{docId}/pages/{pageIdOrName}\nContent-Type: application/json\n\n{\n  \"name\": \"Updated Page Name\",\n  \"subtitle\": \"Updated subtitle\"\n}\n\nDelete Page\n\nDELETE /coda/apis/v1/docs/{docId}/pages/{pageIdOrName}"
      },
      {
        "title": "Tables",
        "body": "List Tables\n\nGET /coda/apis/v1/docs/{docId}/tables\n\nQuery parameters:\n\nlimit - Page size\npageToken - Pagination token\nsortBy - Sort by field\ntableTypes - Filter by table type\n\nGet Table\n\nGET /coda/apis/v1/docs/{docId}/tables/{tableIdOrName}"
      },
      {
        "title": "Columns",
        "body": "List Columns\n\nGET /coda/apis/v1/docs/{docId}/tables/{tableIdOrName}/columns\n\nQuery parameters:\n\nlimit - Page size\npageToken - Pagination token\n\nGet Column\n\nGET /coda/apis/v1/docs/{docId}/tables/{tableIdOrName}/columns/{columnIdOrName}"
      },
      {
        "title": "Rows",
        "body": "List Rows\n\nGET /coda/apis/v1/docs/{docId}/tables/{tableIdOrName}/rows\n\nQuery parameters:\n\nquery - Filter rows by search query\nuseColumnNames - Use column names instead of IDs in response (true/false)\nvalueFormat - Value format (simple, simpleWithArrays, rich)\nsortBy - Sort by column\nlimit - Page size\npageToken - Pagination token\n\nGet Row\n\nGET /coda/apis/v1/docs/{docId}/tables/{tableIdOrName}/rows/{rowIdOrName}\n\nQuery parameters:\n\nuseColumnNames - Use column names instead of IDs\nvalueFormat - Value format\n\nInsert/Upsert Rows\n\nPOST /coda/apis/v1/docs/{docId}/tables/{tableIdOrName}/rows\nContent-Type: application/json\n\n{\n  \"rows\": [\n    {\n      \"cells\": [\n        {\"column\": \"Column Name\", \"value\": \"Cell Value\"},\n        {\"column\": \"Another Column\", \"value\": 123}\n      ]\n    }\n  ],\n  \"keyColumns\": [\"Column Name\"]\n}\n\nUse keyColumns for upsert behavior (update if exists, insert if not)\nRow inserts/upserts are processed asynchronously (returns requestId)\n\nUpdate Row\n\nPUT /coda/apis/v1/docs/{docId}/tables/{tableIdOrName}/rows/{rowIdOrName}\nContent-Type: application/json\n\n{\n  \"row\": {\n    \"cells\": [\n      {\"column\": \"Column Name\", \"value\": \"Updated Value\"}\n    ]\n  }\n}\n\nDelete Row\n\nDELETE /coda/apis/v1/docs/{docId}/tables/{tableIdOrName}/rows/{rowIdOrName}"
      },
      {
        "title": "Formulas",
        "body": "List Formulas\n\nGET /coda/apis/v1/docs/{docId}/formulas\n\nGet Formula\n\nGET /coda/apis/v1/docs/{docId}/formulas/{formulaIdOrName}"
      },
      {
        "title": "Controls",
        "body": "List Controls\n\nGET /coda/apis/v1/docs/{docId}/controls\n\nGet Control\n\nGET /coda/apis/v1/docs/{docId}/controls/{controlIdOrName}"
      },
      {
        "title": "Permissions",
        "body": "Get Sharing Metadata\n\nGET /coda/apis/v1/docs/{docId}/acl/metadata\n\nList Permissions\n\nGET /coda/apis/v1/docs/{docId}/acl/permissions\n\nAdd Permission\n\nPOST /coda/apis/v1/docs/{docId}/acl/permissions\nContent-Type: application/json\n\n{\n  \"access\": \"readonly\",\n  \"principal\": {\n    \"type\": \"email\",\n    \"email\": \"user@example.com\"\n  }\n}\n\nAccess values: readonly, write, comment\n\nDelete Permission\n\nDELETE /coda/apis/v1/docs/{docId}/acl/permissions/{permissionId}"
      },
      {
        "title": "Categories",
        "body": "List Categories\n\nGET /coda/apis/v1/categories"
      },
      {
        "title": "Utilities",
        "body": "Resolve Browser Link\n\nGET /coda/apis/v1/resolveBrowserLink?url={encodedUrl}\n\nConverts a Coda browser URL to API resource information.\n\nGet Mutation Status\n\nGET /coda/apis/v1/mutationStatus/{requestId}\n\nCheck the status of an asynchronous mutation operation."
      },
      {
        "title": "Analytics",
        "body": "List Doc Analytics\n\nGET /coda/apis/v1/analytics/docs\n\nQuery parameters:\n\nisPublished - Filter by published status\nsinceDate - Start date (YYYY-MM-DD)\nuntilDate - End date (YYYY-MM-DD)\nlimit - Page size\npageToken - Pagination token\n\nList Pack Analytics\n\nGET /coda/apis/v1/analytics/packs\n\nGet Analytics Update Time\n\nGET /coda/apis/v1/analytics/updated"
      },
      {
        "title": "Pagination",
        "body": "Coda uses cursor-based pagination with pageToken:\n\nGET /coda/apis/v1/docs?limit=25\n\nResponse includes nextPageToken when more results exist:\n\n{\n  \"items\": [...],\n  \"href\": \"https://coda.io/apis/v1/docs?pageToken=...\",\n  \"nextPageToken\": \"eyJsaW1...\"\n}\n\nUse the nextPageToken value as pageToken in subsequent requests."
      },
      {
        "title": "Asynchronous Mutations",
        "body": "Create, update, and delete operations return HTTP 202 with a requestId:\n\n{\n  \"id\": \"canvas-abc123\",\n  \"requestId\": \"mutate:9f038510-be42-4d16-bccf-3468d38efd57\"\n}\n\nCheck mutation status:\n\nGET /coda/apis/v1/mutationStatus/mutate:9f038510-be42-4d16-bccf-3468d38efd57\n\nResponse:\n\n{\n  \"completed\": true\n}\n\nMutations are generally processed within a few seconds."
      },
      {
        "title": "JavaScript - List Docs",
        "body": "const response = await fetch(\n  'https://gateway.maton.ai/coda/apis/v1/docs?limit=10',\n  {\n    headers: {\n      'Authorization': `Bearer ${process.env.MATON_API_KEY}`\n    }\n  }\n);\nconst data = await response.json();\nconsole.log(data.items);"
      },
      {
        "title": "Python - List Docs",
        "body": "import os\nimport requests\n\nresponse = requests.get(\n    'https://gateway.maton.ai/coda/apis/v1/docs',\n    headers={'Authorization': f'Bearer {os.environ[\"MATON_API_KEY\"]}'},\n    params={'limit': 10}\n)\ndata = response.json()\nfor doc in data['items']:\n    print(f\"{doc['name']}: {doc['id']}\")"
      },
      {
        "title": "Python - Create Doc and Page",
        "body": "import os\nimport requests\n\nheaders = {'Authorization': f'Bearer {os.environ[\"MATON_API_KEY\"]}'}\nbase_url = 'https://gateway.maton.ai/coda/apis/v1'\n\n# Create doc\ndoc_response = requests.post(\n    f'{base_url}/docs',\n    headers=headers,\n    json={'title': 'My New Doc'}\n)\ndoc = doc_response.json()\nprint(f\"Created doc: {doc['id']}\")\n\n# Create page\npage_response = requests.post(\n    f'{base_url}/docs/{doc[\"id\"]}/pages',\n    headers=headers,\n    json={'name': 'First Page', 'subtitle': 'Created via API'}\n)\npage = page_response.json()\nprint(f\"Created page: {page['id']}\")"
      },
      {
        "title": "Python - Insert Rows",
        "body": "import os\nimport requests\n\nheaders = {'Authorization': f'Bearer {os.environ[\"MATON_API_KEY\"]}'}\n\nresponse = requests.post(\n    'https://gateway.maton.ai/coda/apis/v1/docs/{docId}/tables/{tableId}/rows',\n    headers=headers,\n    json={\n        'rows': [\n            {\n                'cells': [\n                    {'column': 'Name', 'value': 'John Doe'},\n                    {'column': 'Email', 'value': 'john@example.com'}\n                ]\n            }\n        ]\n    }\n)\nresult = response.json()\nprint(f\"Request ID: {result['requestId']}\")"
      },
      {
        "title": "Notes",
        "body": "Doc IDs look like s0ekj2vV-v\nPage IDs start with canvas-\nTable and column names can be used instead of IDs\nRow operations require a base table (not views)\nCreate/Update/Delete operations are asynchronous (return requestId)\nNewly created docs may take a moment to be accessible via API (409 error)\nPage-level analytics require Enterprise plan\nIMPORTANT: When using curl commands, use curl -g when URLs contain brackets to disable glob parsing\nIMPORTANT: When piping curl output to jq, environment variables may not expand correctly. Use Python examples instead."
      },
      {
        "title": "Rate Limits",
        "body": "OperationLimitReading data100 requests per 6 secondsWriting data10 requests per 6 secondsWriting doc content5 requests per 10 secondsListing docs4 requests per 6 secondsReading analytics100 requests per 6 seconds"
      },
      {
        "title": "Error Handling",
        "body": "StatusMeaning400Missing Coda connection or invalid request401Invalid or missing Maton API key404Resource not found409Doc not yet accessible (just created)429Rate limited4xx/5xxPassthrough error from Coda API"
      },
      {
        "title": "Troubleshooting: API Key Issues",
        "body": "Check that the MATON_API_KEY environment variable is set:\n\necho $MATON_API_KEY\n\nVerify the API key is valid by listing connections:\n\npython <<'EOF'\nimport urllib.request, os, json\nreq = urllib.request.Request('https://ctrl.maton.ai/connections')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF"
      },
      {
        "title": "Troubleshooting: Invalid App Name",
        "body": "Ensure your URL path starts with coda. For example:\n\nCorrect: https://gateway.maton.ai/coda/apis/v1/docs\nIncorrect: https://gateway.maton.ai/apis/v1/docs"
      },
      {
        "title": "Resources",
        "body": "Coda API Documentation\nCoda API Postman Collection\nCoda API Python Library (codaio)\nMaton Community\nMaton Support"
      }
    ],
    "body": "Coda\n\nAccess the Coda API with managed OAuth authentication. Manage docs, pages, tables, rows, formulas, and controls with full CRUD operations.\n\nQuick Start\n# List your docs\npython <<'EOF'\nimport urllib.request, os, json\nreq = urllib.request.Request('https://gateway.maton.ai/coda/apis/v1/docs')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF\n\nBase URL\nhttps://gateway.maton.ai/coda/apis/v1/{resource}\n\n\nReplace {resource} with the actual Coda API endpoint path. The gateway proxies requests to coda.io/apis/v1 and automatically injects your OAuth token.\n\nAuthentication\n\nAll requests require the Maton API key in the Authorization header:\n\nAuthorization: Bearer $MATON_API_KEY\n\n\nEnvironment Variable: Set your API key as MATON_API_KEY:\n\nexport MATON_API_KEY=\"YOUR_API_KEY\"\n\nGetting Your API Key\nSign in or create an account at maton.ai\nGo to maton.ai/settings\nCopy your API key\nConnection Management\n\nManage your Coda OAuth connections at https://ctrl.maton.ai.\n\nList Connections\npython <<'EOF'\nimport urllib.request, os, json\nreq = urllib.request.Request('https://ctrl.maton.ai/connections?app=coda&status=ACTIVE')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF\n\nCreate Connection\npython <<'EOF'\nimport urllib.request, os, json\ndata = json.dumps({'app': 'coda'}).encode()\nreq = urllib.request.Request('https://ctrl.maton.ai/connections', data=data, method='POST')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nreq.add_header('Content-Type', 'application/json')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF\n\nGet Connection\npython <<'EOF'\nimport urllib.request, os, json\nreq = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF\n\n\nResponse:\n\n{\n  \"connection\": {\n    \"connection_id\": \"f46d34b1-3735-478a-a0d7-54115a16cd46\",\n    \"status\": \"ACTIVE\",\n    \"creation_time\": \"2026-02-12T01:38:10.500238Z\",\n    \"last_updated_time\": \"2026-02-12T01:38:33.545353Z\",\n    \"url\": \"https://connect.maton.ai/?session_token=...\",\n    \"app\": \"coda\",\n    \"metadata\": {}\n  }\n}\n\n\nOpen the returned url in a browser to complete OAuth authorization.\n\nDelete Connection\npython <<'EOF'\nimport urllib.request, os, json\nreq = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}', method='DELETE')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF\n\nSpecifying Connection\n\nIf you have multiple Coda connections, specify which one to use with the Maton-Connection header:\n\npython <<'EOF'\nimport urllib.request, os, json\nreq = urllib.request.Request('https://gateway.maton.ai/coda/apis/v1/docs')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nreq.add_header('Maton-Connection', 'f46d34b1-3735-478a-a0d7-54115a16cd46')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF\n\n\nIf omitted, the gateway uses the default (oldest) active connection.\n\nAPI Reference\nAccount\nGet Current User\nGET /coda/apis/v1/whoami\n\n\nReturns information about the authenticated user.\n\nDocs\nList Docs\nGET /coda/apis/v1/docs\n\n\nQuery parameters:\n\nisOwner - Show only owned docs (true/false)\nquery - Search query\nsourceDoc - Filter by source doc ID\nisStarred - Show only starred docs\ninGallery - Show only gallery docs\nworkspaceId - Filter by workspace\nfolderId - Filter by folder\nlimit - Page size (default: 25, max: 200)\npageToken - Pagination token\nCreate Doc\nPOST /coda/apis/v1/docs\nContent-Type: application/json\n\n{\n  \"title\": \"My New Doc\",\n  \"sourceDoc\": \"optional-source-doc-id\",\n  \"timezone\": \"America/Los_Angeles\",\n  \"folderId\": \"optional-folder-id\"\n}\n\nGet Doc\nGET /coda/apis/v1/docs/{docId}\n\nDelete Doc\nDELETE /coda/apis/v1/docs/{docId}\n\nPages\nList Pages\nGET /coda/apis/v1/docs/{docId}/pages\n\n\nQuery parameters:\n\nlimit - Page size\npageToken - Pagination token\nCreate Page\nPOST /coda/apis/v1/docs/{docId}/pages\nContent-Type: application/json\n\n{\n  \"name\": \"New Page\",\n  \"subtitle\": \"Optional subtitle\",\n  \"parentPageId\": \"optional-parent-page-id\"\n}\n\nGet Page\nGET /coda/apis/v1/docs/{docId}/pages/{pageIdOrName}\n\nUpdate Page\nPUT /coda/apis/v1/docs/{docId}/pages/{pageIdOrName}\nContent-Type: application/json\n\n{\n  \"name\": \"Updated Page Name\",\n  \"subtitle\": \"Updated subtitle\"\n}\n\nDelete Page\nDELETE /coda/apis/v1/docs/{docId}/pages/{pageIdOrName}\n\nTables\nList Tables\nGET /coda/apis/v1/docs/{docId}/tables\n\n\nQuery parameters:\n\nlimit - Page size\npageToken - Pagination token\nsortBy - Sort by field\ntableTypes - Filter by table type\nGet Table\nGET /coda/apis/v1/docs/{docId}/tables/{tableIdOrName}\n\nColumns\nList Columns\nGET /coda/apis/v1/docs/{docId}/tables/{tableIdOrName}/columns\n\n\nQuery parameters:\n\nlimit - Page size\npageToken - Pagination token\nGet Column\nGET /coda/apis/v1/docs/{docId}/tables/{tableIdOrName}/columns/{columnIdOrName}\n\nRows\nList Rows\nGET /coda/apis/v1/docs/{docId}/tables/{tableIdOrName}/rows\n\n\nQuery parameters:\n\nquery - Filter rows by search query\nuseColumnNames - Use column names instead of IDs in response (true/false)\nvalueFormat - Value format (simple, simpleWithArrays, rich)\nsortBy - Sort by column\nlimit - Page size\npageToken - Pagination token\nGet Row\nGET /coda/apis/v1/docs/{docId}/tables/{tableIdOrName}/rows/{rowIdOrName}\n\n\nQuery parameters:\n\nuseColumnNames - Use column names instead of IDs\nvalueFormat - Value format\nInsert/Upsert Rows\nPOST /coda/apis/v1/docs/{docId}/tables/{tableIdOrName}/rows\nContent-Type: application/json\n\n{\n  \"rows\": [\n    {\n      \"cells\": [\n        {\"column\": \"Column Name\", \"value\": \"Cell Value\"},\n        {\"column\": \"Another Column\", \"value\": 123}\n      ]\n    }\n  ],\n  \"keyColumns\": [\"Column Name\"]\n}\n\nUse keyColumns for upsert behavior (update if exists, insert if not)\nRow inserts/upserts are processed asynchronously (returns requestId)\nUpdate Row\nPUT /coda/apis/v1/docs/{docId}/tables/{tableIdOrName}/rows/{rowIdOrName}\nContent-Type: application/json\n\n{\n  \"row\": {\n    \"cells\": [\n      {\"column\": \"Column Name\", \"value\": \"Updated Value\"}\n    ]\n  }\n}\n\nDelete Row\nDELETE /coda/apis/v1/docs/{docId}/tables/{tableIdOrName}/rows/{rowIdOrName}\n\nFormulas\nList Formulas\nGET /coda/apis/v1/docs/{docId}/formulas\n\nGet Formula\nGET /coda/apis/v1/docs/{docId}/formulas/{formulaIdOrName}\n\nControls\nList Controls\nGET /coda/apis/v1/docs/{docId}/controls\n\nGet Control\nGET /coda/apis/v1/docs/{docId}/controls/{controlIdOrName}\n\nPermissions\nGet Sharing Metadata\nGET /coda/apis/v1/docs/{docId}/acl/metadata\n\nList Permissions\nGET /coda/apis/v1/docs/{docId}/acl/permissions\n\nAdd Permission\nPOST /coda/apis/v1/docs/{docId}/acl/permissions\nContent-Type: application/json\n\n{\n  \"access\": \"readonly\",\n  \"principal\": {\n    \"type\": \"email\",\n    \"email\": \"user@example.com\"\n  }\n}\n\n\nAccess values: readonly, write, comment\n\nDelete Permission\nDELETE /coda/apis/v1/docs/{docId}/acl/permissions/{permissionId}\n\nCategories\nList Categories\nGET /coda/apis/v1/categories\n\nUtilities\nResolve Browser Link\nGET /coda/apis/v1/resolveBrowserLink?url={encodedUrl}\n\n\nConverts a Coda browser URL to API resource information.\n\nGet Mutation Status\nGET /coda/apis/v1/mutationStatus/{requestId}\n\n\nCheck the status of an asynchronous mutation operation.\n\nAnalytics\nList Doc Analytics\nGET /coda/apis/v1/analytics/docs\n\n\nQuery parameters:\n\nisPublished - Filter by published status\nsinceDate - Start date (YYYY-MM-DD)\nuntilDate - End date (YYYY-MM-DD)\nlimit - Page size\npageToken - Pagination token\nList Pack Analytics\nGET /coda/apis/v1/analytics/packs\n\nGet Analytics Update Time\nGET /coda/apis/v1/analytics/updated\n\nPagination\n\nCoda uses cursor-based pagination with pageToken:\n\nGET /coda/apis/v1/docs?limit=25\n\n\nResponse includes nextPageToken when more results exist:\n\n{\n  \"items\": [...],\n  \"href\": \"https://coda.io/apis/v1/docs?pageToken=...\",\n  \"nextPageToken\": \"eyJsaW1...\"\n}\n\n\nUse the nextPageToken value as pageToken in subsequent requests.\n\nAsynchronous Mutations\n\nCreate, update, and delete operations return HTTP 202 with a requestId:\n\n{\n  \"id\": \"canvas-abc123\",\n  \"requestId\": \"mutate:9f038510-be42-4d16-bccf-3468d38efd57\"\n}\n\n\nCheck mutation status:\n\nGET /coda/apis/v1/mutationStatus/mutate:9f038510-be42-4d16-bccf-3468d38efd57\n\n\nResponse:\n\n{\n  \"completed\": true\n}\n\n\nMutations are generally processed within a few seconds.\n\nCode Examples\nJavaScript - List Docs\nconst response = await fetch(\n  'https://gateway.maton.ai/coda/apis/v1/docs?limit=10',\n  {\n    headers: {\n      'Authorization': `Bearer ${process.env.MATON_API_KEY}`\n    }\n  }\n);\nconst data = await response.json();\nconsole.log(data.items);\n\nPython - List Docs\nimport os\nimport requests\n\nresponse = requests.get(\n    'https://gateway.maton.ai/coda/apis/v1/docs',\n    headers={'Authorization': f'Bearer {os.environ[\"MATON_API_KEY\"]}'},\n    params={'limit': 10}\n)\ndata = response.json()\nfor doc in data['items']:\n    print(f\"{doc['name']}: {doc['id']}\")\n\nPython - Create Doc and Page\nimport os\nimport requests\n\nheaders = {'Authorization': f'Bearer {os.environ[\"MATON_API_KEY\"]}'}\nbase_url = 'https://gateway.maton.ai/coda/apis/v1'\n\n# Create doc\ndoc_response = requests.post(\n    f'{base_url}/docs',\n    headers=headers,\n    json={'title': 'My New Doc'}\n)\ndoc = doc_response.json()\nprint(f\"Created doc: {doc['id']}\")\n\n# Create page\npage_response = requests.post(\n    f'{base_url}/docs/{doc[\"id\"]}/pages',\n    headers=headers,\n    json={'name': 'First Page', 'subtitle': 'Created via API'}\n)\npage = page_response.json()\nprint(f\"Created page: {page['id']}\")\n\nPython - Insert Rows\nimport os\nimport requests\n\nheaders = {'Authorization': f'Bearer {os.environ[\"MATON_API_KEY\"]}'}\n\nresponse = requests.post(\n    'https://gateway.maton.ai/coda/apis/v1/docs/{docId}/tables/{tableId}/rows',\n    headers=headers,\n    json={\n        'rows': [\n            {\n                'cells': [\n                    {'column': 'Name', 'value': 'John Doe'},\n                    {'column': 'Email', 'value': 'john@example.com'}\n                ]\n            }\n        ]\n    }\n)\nresult = response.json()\nprint(f\"Request ID: {result['requestId']}\")\n\nNotes\nDoc IDs look like s0ekj2vV-v\nPage IDs start with canvas-\nTable and column names can be used instead of IDs\nRow operations require a base table (not views)\nCreate/Update/Delete operations are asynchronous (return requestId)\nNewly created docs may take a moment to be accessible via API (409 error)\nPage-level analytics require Enterprise plan\nIMPORTANT: When using curl commands, use curl -g when URLs contain brackets to disable glob parsing\nIMPORTANT: When piping curl output to jq, environment variables may not expand correctly. Use Python examples instead.\nRate Limits\nOperation\tLimit\nReading data\t100 requests per 6 seconds\nWriting data\t10 requests per 6 seconds\nWriting doc content\t5 requests per 10 seconds\nListing docs\t4 requests per 6 seconds\nReading analytics\t100 requests per 6 seconds\nError Handling\nStatus\tMeaning\n400\tMissing Coda connection or invalid request\n401\tInvalid or missing Maton API key\n404\tResource not found\n409\tDoc not yet accessible (just created)\n429\tRate limited\n4xx/5xx\tPassthrough error from Coda API\nTroubleshooting: API Key Issues\nCheck that the MATON_API_KEY environment variable is set:\necho $MATON_API_KEY\n\nVerify the API key is valid by listing connections:\npython <<'EOF'\nimport urllib.request, os, json\nreq = urllib.request.Request('https://ctrl.maton.ai/connections')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF\n\nTroubleshooting: Invalid App Name\nEnsure your URL path starts with coda. For example:\nCorrect: https://gateway.maton.ai/coda/apis/v1/docs\nIncorrect: https://gateway.maton.ai/apis/v1/docs\nResources\nCoda API Documentation\nCoda API Postman Collection\nCoda API Python Library (codaio)\nMaton Community\nMaton Support"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/byungkyu/coda-api",
    "publisherUrl": "https://clawhub.ai/byungkyu/coda-api",
    "owner": "byungkyu",
    "version": "1.0.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/coda-api",
    "downloadUrl": "https://openagent3.xyz/downloads/coda-api",
    "agentUrl": "https://openagent3.xyz/skills/coda-api/agent",
    "manifestUrl": "https://openagent3.xyz/skills/coda-api/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/coda-api/agent.md"
  }
}