文档

Coda

试用

通过托管 OAuth 网关管理 Coda 文档、页面、表格、行、公式与控件。

它能做什么

通过托管 OAuth 网关调用 Coda API。所有请求发送到 api.maton.ai/coda/apis/v1,在请求头中以 Bearer Token 形式携带 Maton API Key,网关自动注入 Coda 的 OAuth 凭证并转发到 coda.io/apis/v1,无需手动管理令牌。支持对文档、页面、表格、行、列、公式、控件进行完整增删改查,同时覆盖权限(acl)、分类、分析、浏览器链接解析等接口。多个 Coda 账号可通过 /connections 分别建立连接,再用 Maton-Connection 请求头指定使用哪一个。写入操作为异步执行,返回 requestId 后通过 mutationStatus 轮询完成状态。

什么时候用它

  • 列出与搜索 Coda 文档
  • 在表格所属文档下创建页面并插入行
  • 读取或更新列、公式与控件
  • 管理文档的共享权限

技能文档

Coda

Access the Coda API with managed OAuth authentication. Manage docs, pages, tables, rows, formulas, and controls with full CRUD operations.

Quick Start

# List your docs
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/coda/apis/v1/docs')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Base URL

https://api.maton.ai/coda/apis/v1/{resource}

Maton proxies requests to coda.io/apis/v1 and automatically injects your OAuth token.

Authentication

All requests require the Maton API key in the Authorization header:

Authorization: Bearer $MATON_API_KEY

Environment Variable: Set your API key as MATON_API_KEY:

export MATON_API_KEY="YOUR_API_KEY"

Getting Your API Key

  1. Sign in or create an account at maton.ai
  2. Go to maton.ai/settings
  3. Copy your API key

Connection Management

Manage your Coda OAuth connections at https://api.maton.ai.

List Connections

python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections?app=coda&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Create Connection

python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'coda'}).encode()
req = urllib.request.Request('https://api.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Get Connection

python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Response:

{
  "connection": {
    "connection_id": "{connection_id}",
    "status": "ACTIVE",
    "creation_time": "2026-02-12T01:38:10.500238Z",
    "last_updated_time": "2026-02-12T01:38:33.545353Z",
    "url": "https://connect.maton.ai/?session_token=...",
    "app": "coda",
    "metadata": {}
  }
}

Open the returned url in a browser to complete OAuth authorization.

Delete Connection

python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Specifying Connection

If you have multiple Coda connections, specify which one to use with the Maton-Connection header:

python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/coda/apis/v1/docs')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', '{connection_id}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

If you have multiple connections, always include this header to ensure requests go to the intended account.

Security & Permissions

  • Access is scoped to docs, pages, tables, rows, and formulas within the connected Coda account.
  • All write operations require explicit user approval. Before executing any create, update, or delete call, confirm the target resource and intended effect with the user.

API Reference

Account

Get Current User

GET /coda/apis/v1/whoami

Returns information about the authenticated user.

Docs

List Docs

GET /coda/apis/v1/docs

Query parameters:

  • isOwner - Show only owned docs (true/false)
  • query - Search query
  • sourceDoc - Filter by source doc ID
  • isStarred - Show only starred docs
  • inGallery - Show only gallery docs
  • workspaceId - Filter by workspace
  • folderId - Filter by folder
  • limit - Page size (default: 25, max: 200)
  • pageToken - Pagination token

Create Doc

POST /coda/apis/v1/docs
Content-Type: application/json

{
  "title": "My New Doc",
  "sourceDoc": "optional-source-doc-id",
  "timezone": "America/Los_Angeles",
  "folderId": "optional-folder-id"
}

Get Doc

GET /coda/apis/v1/docs/{docId}

Delete Doc

DELETE /coda/apis/v1/docs/{docId}

Pages

List Pages

GET /coda/apis/v1/docs/{docId}/pages

Query parameters:

  • limit - Page size
  • pageToken - Pagination token

Create Page

POST /coda/apis/v1/docs/{docId}/pages
Content-Type: application/json

{
  "name": "New Page",
  "subtitle": "Optional subtitle",
  "parentPageId": "optional-parent-page-id"
}

Get Page

GET /coda/apis/v1/docs/{docId}/pages/{pageIdOrName}

Update Page

PUT /coda/apis/v1/docs/{docId}/pages/{pageIdOrName}
Content-Type: application/json

{
  "name": "Updated Page Name",
  "subtitle": "Updated subtitle"
}

Delete Page

DELETE /coda/apis/v1/docs/{docId}/pages/{pageIdOrName}

Tables

List Tables

GET /coda/apis/v1/docs/{docId}/tables

Query parameters:

  • limit - Page size
  • pageToken - Pagination token
  • sortBy - Sort by field
  • tableTypes - Filter by table type

Get Table

GET /coda/apis/v1/docs/{docId}/tables/{tableIdOrName}

Columns

List Columns

GET /coda/apis/v1/docs/{docId}/tables/{tableIdOrName}/columns

Query parameters:

  • limit - Page size
  • pageToken - Pagination token

Get Column

GET /coda/apis/v1/docs/{docId}/tables/{tableIdOrName}/columns/{columnIdOrName}

Rows

List Rows

GET /coda/apis/v1/docs/{docId}/tables/{tableIdOrName}/rows

Query parameters:

  • query - Filter rows by search query
  • useColumnNames - Use column names instead of IDs in response (true/false)
  • valueFormat - Value format (simple, simpleWithArrays, rich)
  • sortBy - Sort by column
  • limit - Page size
  • pageToken - Pagination token

Get Row

GET /coda/apis/v1/docs/{docId}/tables/{tableIdOrName}/rows/{rowIdOrName}

Query parameters:

  • useColumnNames - Use column names instead of IDs
  • valueFormat - Value format

Insert/Upsert Rows

POST /coda/apis/v1/docs/{docId}/tables/{tableIdOrName}/rows
Content-Type: application/json

{
  "rows": [
    {
      "cells": [
        {"column": "Column Name", "value": "Cell Value"},
        {"column": "Another Column", "value": 123}
      ]
    }
  ],
  "keyColumns": ["Column Name"]
}
  • Use keyColumns for upsert behavior (update if exists, insert if not)
  • Row inserts/upserts are processed asynchronously (returns requestId)

Update Row

PUT /coda/apis/v1/docs/{docId}/tables/{tableIdOrName}/rows/{rowIdOrName}
Content-Type: application/json

{
  "row": {
    "cells": [
      {"column": "Column Name", "value": "Updated Value"}
    ]
  }
}

Delete Row

DELETE /coda/apis/v1/docs/{docId}/tables/{tableIdOrName}/rows/{rowIdOrName}

Formulas

List Formulas

GET /coda/apis/v1/docs/{docId}/formulas

Get Formula

GET /coda/apis/v1/docs/{docId}/formulas/{formulaIdOrName}

Controls

List Controls

GET /coda/apis/v1/docs/{docId}/controls

Get Control

GET /coda/apis/v1/docs/{docId}/controls/{controlIdOrName}

Permissions

Get Sharing Metadata

GET /coda/apis/v1/docs/{docId}/acl/metadata

List Permissions

GET /coda/apis/v1/docs/{docId}/acl/permissions

Add Permission

POST /coda/apis/v1/docs/{docId}/acl/permissions
Content-Type: application/json

{
  "access": "readonly",
  "principal": {
    "type": "email",
    "email": "user@example.com"
  }
}

Access values: readonly, write, comment

Delete Permission

DELETE /coda/apis/v1/docs/{docId}/acl/permissions/{permissionId}

Categories

List Categories

GET /coda/apis/v1/categories

Utilities

GET /coda/apis/v1/resolveBrowserLink?url={encodedUrl}

Converts a Coda browser URL to API resource information.

Get Mutation Status

GET /coda/apis/v1/mutationStatus/{requestId}

Check the status of an asynchronous mutation operation.

Analytics

List Doc Analytics

GET /coda/apis/v1/analytics/docs

Query parameters:

  • isPublished - Filter by published status
  • sinceDate - Start date (YYYY-MM-DD)
  • untilDate - End date (YYYY-MM-DD)
  • limit - Page size
  • pageToken - Pagination token

List Pack Analytics

GET /coda/apis/v1/analytics/packs

Get Analytics Update Time

GET /coda/apis/v1/analytics/updated

Pagination

Coda uses cursor-based pagination with pageToken:

GET /coda/apis/v1/docs?limit=25

Response includes nextPageToken when more results exist:

{
  "items": [...],
  "href": "https://coda.io/apis/v1/docs?pageToken=...",
  "nextPageToken": "eyJsaW1..."
}

Use the nextPageToken value as pageToken in subsequent requests.

Asynchronous Mutations

Create, update, and delete operations return HTTP 202 with a requestId:

{
  "id": "canvas-abc123",
  "requestId": "mutate:9f038510-be42-4d16-bccf-3468d38efd57"
}

Check mutation status:

GET /coda/apis/v1/mutationStatus/mutate:9f038510-be42-4d16-bccf-3468d38efd57

Response:

{
  "completed": true
}

Mutations are generally processed within a few seconds.

Code Examples

JavaScript - List Docs

const response = await fetch(
  'https://api.maton.ai/coda/apis/v1/docs?limit=10',
  {
    headers: {
      'Authorization': `Bearer ${process.env.MATON_API_KEY}`
    }
  }
);
const data = await response.json();
console.log(data.items);

Python - List Docs

import os
import requests

response = requests.get(
    'https://api.maton.ai/coda/apis/v1/docs',
    headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'},
    params={'limit': 10}
)
data = response.json()
for doc in data['items']:
    print(f"{doc['name']}: {doc['id']}")

Python - Create Doc and Page

import os
import requests

headers = {'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}
base_url = 'https://api.maton.ai/coda/apis/v1'

# Create doc
doc_response = requests.post(
    f'{base_url}/docs',
    headers=headers,
    json={'title': 'My New Doc'}
)
doc = doc_response.json()
print(f"Created doc: {doc['id']}")

# Create page
page_response = requests.post(
    f'{base_url}/docs/{doc["id"]}/pages',
    headers=headers,
    json={'name': 'First Page', 'subtitle': 'Created via API'}
)
page = page_response.json()
print(f"Created page: {page['id']}")

Python - Insert Rows

import os
import requests

headers = {'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}

response = requests.post(
    'https://api.maton.ai/coda/apis/v1/docs/{docId}/tables/{tableId}/rows',
    headers=headers,
    json={
        'rows': [
            {
                'cells': [
                    {'column': 'Name', 'value': 'John Doe'},
                    {'column': 'Email', 'value': 'john@example.com'}
                ]
            }
        ]
    }
)
result = response.json()
print(f"Request ID: {result['requestId']}")

Notes

  • Doc IDs look like s0ekj2vV-v
  • Page IDs start with canvas-
  • Table and column names can be used instead of IDs
  • Row operations require a base table (not views)
  • Create/Update/Delete operations are asynchronous (return requestId)
  • Newly created docs may take a moment to be accessible via API (409 error)
  • Page-level analytics require Enterprise plan
  • IMPORTANT: When using curl commands, use curl -g when URLs contain brackets to disable glob parsing
  • IMPORTANT: When piping curl output to jq, environment variables may not expand correctly. Use Python examples instead.

Rate Limits

OperationLimit
Reading data100 requests per 6 seconds
Writing data10 requests per 6 seconds
Writing doc content5 requests per 10 seconds
Listing docs4 requests per 6 seconds
Reading analytics100 requests per 6 seconds

Error Handling

StatusMeaning
400Missing Coda connection or invalid request
401Invalid or missing Maton API key
404Resource not found
409Doc not yet accessible (just created)
429Rate limited
4xx/5xxPassthrough error from Coda API

Troubleshooting: API Key Issues

  1. Check that the MATON_API_KEY environment variable is set:
echo $MATON_API_KEY
  1. Verify the API key is valid by listing connections:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Troubleshooting: Invalid App Name

  1. Ensure your URL path starts with coda. For example:
  • Correct: https://api.maton.ai/coda/apis/v1/docs
  • Incorrect: https://api.maton.ai/apis/v1/docs

Resources

常见问题

如何完成认证?
在请求头中以 Bearer Token 形式传递 Maton API Key,网关会自动注入 Coda 的 OAuth 凭证再转发请求,无需手动刷新令牌。
可以同时接入多个 Coda 账号吗?
可以。通过 POST /connections 为每个账号建立独立连接,每次请求时用 Maton-Connection 请求头指定要使用的连接。
写入操作会立即生效吗?
不会。创建、更新、删除操作返回 HTTP 202 和 requestId,需轮询 GET /mutationStatus/{requestId},直到 completed 为 true 才表示执行完成。

相关技能

通过托管 OAuth 接入 Cognito Forms,可列出表单、管理条目并生成 PDF 文档。

145 次安装3 星标

通过托管 OAuth 调用 Google Docs API,实现文档创建、读写与样式管理。

282 次安装8 星标

通过托管 OAuth 代理网关对接 Airtable,对 Base、表和记录执行增删改查。

298 次安装15 星标

通过托管 OAuth 认证,访问并管理 ClickUp 工作区、空间、文件夹、清单与任务等数据。

611 次安装12 星标

通过托管 OAuth 调用 Confluence Cloud API,管理页面、空间、博客、评论与附件。

43 次安装

通过 Microsoft Graph 接口和托管 OAuth,读写 OneNote 的笔记本、分区、分区组与页面。

32 次安装1 星标