Coda to SharePoint Migration: Methods, API Limits & Data Mapping
No native path exists from Coda to SharePoint. Learn every migration method, API rate limits, column type mapping, and how to avoid the 5,000-item threshold trap.
There is no native migration path from Coda to SharePoint. No importer, no connector, no "Move to SharePoint" button. SharePoint's built-in migration tools (SPMT, Migration Manager) support file shares and on-premises SharePoint — not Coda. Coda's export options top out at CSV for tables and PDF for pages. Neither platform offers a direct bridge to the other.
The core problem is architectural. Coda uses an "everything is a doc" model where a single document contains rich-text canvas pages, relational tables with formulas and lookups, and inline attachments — all interleaved. SharePoint enforces a strict separation of concerns:
- Lists (or Microsoft Lists): Typed column storage for structured data — text, number, choice, person, lookup, managed metadata.
- Site Pages:
.aspxfiles composed of Web Part JSON structures arranged viacanvasLayout. - Document Libraries: File storage with versioning and metadata columns.
A single Coda doc with 5 pages of mixed rich text and 3 embedded tables must be decomposed into up to 3 SharePoint Lists, 5 Site Pages, and a Document Library for attachments. There is no 1:1 transfer. You must extract, split, transform, and rebuild.
This guide covers the real methods, the hard API constraints on both sides, and the field-mapping decisions that determine whether your migration preserves data or silently drops it.
For teams evaluating the reverse direction, see our SharePoint to Coda Migration guide.
Migration Methods Compared
| Method | Fidelity | Tables → Lists | Pages → Site Pages | Attachments | Automation | Best For |
|---|---|---|---|---|---|---|
| Manual CSV Export → Import | Low–Medium | ✅ (flat only) | ❌ | Manual re-upload | ❌ | Small workspaces (<10 tables) |
| Copy-Paste via Excel | Low | Partial | ❌ | ❌ | ❌ | Quick one-off table transfers |
| Zapier / Make (iPaaS) | Medium | ✅ (row-by-row) | ❌ | ❌ | ✅ | Ongoing sync, small lists |
| API-Driven Scripts (Coda API + Graph API) | High | ✅ | Partial (text-only web parts) | ✅ (separate upload) | ✅ | Full workspace migrations |
| ClonePartner Managed Migration | Highest | ✅ | ✅ | ✅ | ✅ | Complex workspaces, zero downtime |
Manual CSV Export → SharePoint Import
Best for: Small workspaces with fewer than 10 tables and no canvas page content.
Download Coda tables as CSVs, open in Excel to clean encoding issues, then import into SharePoint via New → List → From Excel. Manually re-create canvas pages as SharePoint Site Pages and re-upload any attachments to a Document Library.
What you lose: Relational lookups (flattened to display values), formulas (exported as static values), canvas pages, inline images, timestamps, edit history, and automations. Tables over 10,000 rows require manual batching.
Zapier / Make (iPaaS)
Best for: Ongoing synchronization of small, flat Coda tables (under 1,000 rows) to SharePoint Lists.
Both platforms offer Coda and SharePoint connectors that work row-by-row: trigger on "New or Updated Row in Coda," then "Create Item in SharePoint List."
iPaaS is not a migration engine. These tools are designed for ongoing sync of simple flat rows, not historical migration of entire workspaces. They cannot migrate canvas page content, cannot handle bulk historical data (triggers fire on changes, not existing rows), and require custom transformation steps for multi-select and lookup columns. (zapier.com)
API-Driven Custom Scripts
Best for: Full workspace migrations where you need control over every field mapping and transformation.
The pipeline:
- Extract from Coda: Use the Coda API to pull all tables, columns, rows, page content, and attachment URLs
- Transform: Map Coda column types to SharePoint equivalents, resolve lookups, convert rich text to HTML
- Create SharePoint Lists: Use Microsoft Graph API with column definitions
- Insert rows: Batch via the listItems endpoint
- Create Site Pages: Use the Graph API pages endpoint with
canvasLayoutJSON - Upload attachments: Use Graph DriveItem upload endpoints
- Relink: Rewrite all internal URLs to point to new SharePoint locations
This approach gives you the highest fidelity short of a managed migration, but expect 40–80 hours of engineering time for a workspace with 20+ tables and 50+ pages. Coda's API rate limits add significant wall-clock time for large datasets.
Exporting Data from Coda: Formats and Limitations
Coda's native export options are limited (help.coda.io):
- Table → CSV: Options → Download as CSV. Exports flat rows only.
- Page/Doc → PDF: Print & PDF → Export to PDF. Visual output, no structured data.
- Bulk Export: Account Settings → Advanced Settings → Export My Data. Generates
.txtand.csvfiles for all docs you own. - JSON via API: Best for lookups, people fields, hyperlinks, images, row IDs, and delta sync logic.
- HTML via Admin API: Enterprise-only. Useful for page content extraction but fails on docs above 125 MB. (help.coda.io)
Bulk export only covers docs you own. Enterprise org admins have additional export options through the admin API. Non-Enterprise users cannot export workspace docs owned by other users.
What every manual export loses:
- Relational lookups: CSV flattens lookup columns to display values. The table relationship is gone.
- Inline images: Not included in CSV exports. PDF captures them visually but not as extractable files.
- Formulas: Exported as computed values, not formulas.
- Metadata: Created/modified timestamps, author info, and edit history are not included.
- Rich text formatting: Canvas content exported as
.txtstrips all formatting — headings, bold, callouts, embeds.
PDF is a reference format, not a migration format. Keep PDFs for side-by-side QA, legal archive, or editorial review. Do not treat them as the source for editable SharePoint pages.
For a detailed walkthrough of every export path, see our How to Export from Coda guide.
Coda API Limits You Must Know Before Migrating
The Coda API is the only way to extract structured data with relationships, page content, and metadata intact. But it has hard limits that directly shape your migration timeline.
The 125 MB Doc Wall
Plan around this before writing extraction code. Coda docs at or above 125 MB (excluding attachments) are completely blocked from API access. The API will refuse all requests — no partial reads, no workaround. You must split the doc below 125 MB before automated extraction can begin. (help.coda.io)
To bypass the 125 MB limit: duplicate the oversized doc, delete half the data from the original, delete the other half from the duplicate, and run your migration scripts against the two smaller docs.
Rate Limits
| Operation | Limit | Scope |
|---|---|---|
| Read requests | 100 per 6 seconds | Per-user, across all docs |
| Write requests (POST/PUT/PATCH) | 10 per 6 seconds | Per-user, across all docs |
| Write doc content | 5 per 10 seconds | Per-user, across all docs |
| List docs | 4 per 6 seconds | Per-user |
| Request body size | 2 MB max | Per request |
| Row payload | 85 KB max | Per row |
These limits apply identically across Free, Pro, Team, and Enterprise accounts. Write mutations return HTTP 202 (accepted and queued), not 200 — your script must poll the getMutationStatus endpoint to confirm completion before proceeding. Because limits are enforced per-user across all docs, running concurrent extraction scripts without a centralized queue will immediately result in HTTP 429 errors. (coda.io)
Pagination and Extraction Throughput
The listRows endpoint returns paginated results with a nextPageToken. For tables with thousands of rows, loop through pages while respecting the 100 requests/6 seconds read limit. Use valueFormat=rich when you need lookups, images, people fields, or formatted text — that's the difference between a flat export and a usable migration payload.
import requests
import time
BASE = "https://coda.io/apis/v1"
HEADERS = {"Authorization": "Bearer YOUR_API_TOKEN"}
def extract_all_rows(doc_id, table_id):
rows = []
page_token = None
while True:
params = {"limit": 500, "valueFormat": "rich"}
if page_token:
params["pageToken"] = page_token
resp = requests.get(
f"{BASE}/docs/{doc_id}/tables/{table_id}/rows",
headers=HEADERS, params=params
)
if resp.status_code == 429:
time.sleep(6) # Back off on rate limit
continue
data = resp.json()
rows.extend(data["items"])
page_token = data.get("nextPageToken")
if not page_token:
break
time.sleep(0.07) # Stay under 100 req/6s
return rowsCoda also supports delta reads via syncToken and query filters in the form <column_id_or_name>:<value>. Note that useColumnNames=true is fragile — renamed columns will break your code. (coda.io)
At maximum throughput, extracting 50,000 rows takes approximately 50 minutes of API time. For more on Coda's API constraints in a migration context, see our Coda to Confluence Migration guide — the same platform-wide limits apply.
Mapping Coda Tables to SharePoint Lists
This is the most technically involved part of the migration. Coda's column types don't map 1:1 to SharePoint List column types, and the differences create silent data loss if you don't plan the mapping before loading a single row.
Column Type Mapping Reference
| Coda Column Type | SharePoint Column Type | Notes |
|---|---|---|
| Text | Single line of text (max 255 chars) | Use "Multiple lines" for longer content |
| Number | Number | Precision differences may apply |
| Currency | Currency | Map currency code manually |
| Percent | Number (formatted) | No native percent type in SP; format post-import |
| Date | DateTime | Coda stores ISO 8601; SP expects the same |
| Date and Time | DateTime | Direct mapping |
| Checkbox | Yes/No (Boolean) | Direct mapping |
| Select (single) | Choice | Migrate option values explicitly |
| Select (multi) | Choice (allow multiple) | Direct mapping |
| Person | Person or Group | Requires Entra ID (Azure AD) lookup; Coda stores email |
| Lookup | Lookup column | Requires target list to exist first |
| Formula | Calculated column | Only simple formulas translate; most need manual rebuild |
| Button | ❌ No equivalent | Rebuild as Power Automate flow |
| Image | Image column or attachment | See attachment section below |
| Hyperlink | Hyperlink or Picture | Direct mapping |
| Scale / Slider | Number | Display formatting lost |
| Relation (cross-table) | Lookup column | Must create target list before source |
Field Mapping Best Practices
Before loading data, follow these non-negotiables:
- Create target lists and columns before the load. Define the full schema in SharePoint first.
- Add a
CodaRowIdcolumn to every target list. This gives you a stable foreign key for validation and relinking. - Store original metadata in explicit columns. SharePoint won't preserve Coda's
createdBy,createdAt, ormodifiedAtvalues during a standard Graph API import. CreateOriginalCreatedAt,OriginalUpdatedAt, andOriginalAuthorcolumns. (learn.microsoft.com) - Load parent lists first, then child lists, then resolve lookups. Topological sorting of table dependencies prevents Lookup column failures.
For Person fields, Microsoft's Graph API often requires the FieldNameLookupId pattern rather than the simpler field payloads shown in basic create-item documentation. Coda stores people as email addresses — these must be resolved to Entra ID object IDs or User Principal Names (UPNs) before insertion. Test Person and Lookup columns on a staging list before any bulk load. (learn.microsoft.com)
For formulas, evaluate Coda formulas to their last-known static values during extraction and write them as standard text/number fields. Only recreate the formula as a SharePoint calculated column if it's simple enough to translate directly — SharePoint calculated columns use a completely different syntax.
For tags and categories, use Choice columns when the taxonomy is small and stable. Use Managed Metadata when you need controlled enterprise terms across sites.
If you've previously navigated Mapping Notion Databases to SharePoint Lists, the structural principles here are similar.
The SharePoint 5,000-Item View Threshold
This is a query throttle, not a storage limit. SharePoint Lists can hold up to 30 million items. But any view, filter, or sort that touches more than 5,000 un-indexed rows triggers a throttle error. The underlying database resorts to row-level locking, blocking other users from accessing that data.
If you import a 12,000-row Coda table into a SharePoint List without indexing columns first, the default "All Items" view will break immediately.
Pre-migration checklist for large tables:
- Create the SharePoint List with all columns before importing data
- Index the columns you'll filter and sort on (max 20 indexed columns per list)
- Import data in batches via the Graph API, not as a single CSV dump
- Create filtered views that return fewer than 5,000 items per view
Not all column types can be indexed. Microsoft's large-lists guidance confirms that single-value Lookup, Person, and Managed Metadata fields can be indexed, while multi-valued Lookup, Person, Managed Metadata, multi-choice, calculated, and multiple lines of text columns cannot. If your Coda design relies on multi-value relation fields, don't assume SharePoint will support the same shape at scale. (learn.microsoft.com)
Row size limit: Each SharePoint list item has an 8,000-byte row limit. If your Coda table has many wide text columns, you may hit this before hitting the row count threshold.
Lookup Column and Permission Limits
SharePoint allows a maximum of 12 lookup-type columns (including Person/Group and Managed Metadata) per list view. If your Coda doc has tables with 15+ cross-table lookups, you'll need to split some into separate views or restructure the relationships.
Permissions can also become a scale problem. SharePoint supports up to 50,000 unique permission scopes in a list or library, but Microsoft recommends staying under 5,000. If your Coda design implied per-row privacy, test that model before copying it into a large SharePoint list. (learn.microsoft.com)
Migrating Coda Canvas Pages to SharePoint Site Pages
This is where most migrations either stall or lose significant fidelity. Coda canvas pages are rich text documents with embedded tables, interactive controls, buttons, and collapsible sections. SharePoint Site Pages use a completely different architecture.
Extracting Coda Page Content
Use the Coda API's POST /docs/{docId}/pages/{pageId}/export endpoint to generate an asynchronous HTML or Markdown payload. Enterprise admins can also use the Admin API for HTML export. The content is returned as a proprietary JSON/HTML hybrid that requires parsing and cleanup before it can be inserted into SharePoint's innerHtml fields.
Building SharePoint Site Pages via Graph API
Since April 2024, Microsoft's Graph API supports creating SharePoint Site Pages programmatically via POST /sites/{site-id}/pages. You cannot push raw HTML into a SharePoint page — you must construct a sitePage resource with sanitized HTML wrapped in supported Web Parts within a canvasLayout structure. (learn.microsoft.com)
Modern SharePoint pages are composed of:
- horizontalSections: The rows of the page
- columns: The layout grids (e.g., one-third, two-thirds)
- webparts: The content blocks — only
textWebPartand a fixed set of standard web parts (Image, Quick Links, Divider, Button, People, YouTube Embed, Document Embed) are supported
{
"@odata.type": "#microsoft.graph.sitePage",
"name": "migrated-coda-page.aspx",
"title": "Migrated Coda Page",
"pageLayout": "article",
"canvasLayout": {
"horizontalSections": [
{
"layout": "oneColumn",
"columns": [
{
"webparts": [
{
"@odata.type": "#microsoft.graph.textWebPart",
"innerHtml": "<p>Sanitized content extracted from Coda</p>"
}
]
}
]
}
]
}
}What Converts and What Doesn't
| Coda Element | SharePoint Equivalent | Fidelity |
|---|---|---|
| Headings (H1–H3) | HTML headings in Text Web Part | ✅ High |
| Bold, italic, lists | HTML in Text Web Part | ✅ High |
| Inline images | Image Web Part (separate upload) | ⚠️ Requires URL rewriting |
| Embedded tables | List Web Part or embed | ⚠️ Must reference existing List |
| Callouts/toggles | No native equivalent | ❌ Lost or flattened |
| Buttons/controls | No native equivalent | ❌ Rebuild as Power Automate |
| @mentions | No programmatic equivalent | ❌ Lost |
| Comments | Not supported via Pages API | ❌ Lost |
| Formulas in text | No equivalent | ❌ Lost |
Graph API Web Part limitation: Only standard web parts listed in Microsoft's documentation are supported when creating pages via the API. Custom SPFx web parts and some native web parts may not render correctly when created programmatically. (learn.microsoft.com)
Slug and URL Planning
In SharePoint, the page name becomes part of the .aspx URL. If the old Coda content was linked from other systems, build an old-to-new URL map and rewrite internal links only after the final SharePoint URLs are confirmed. Upload images and files first so final URLs already exist when you create the pages.
Handling Attachments and Inline Images
Coda stores file attachments and inline images on its own CDN. These URLs are temporary — they expire and are not guaranteed to work after migration. Every image and file must be:
- Downloaded from Coda's CDN during extraction
- Uploaded to a SharePoint Document Library via the Graph API
- Relinked — every reference in migrated pages and list items rewritten to point to the new SharePoint URL
Upload Constraints
For files up to 4 MB, use the simple Graph API upload:
PUT /sites/{site-id}/drive/root:/{folder}/{filename}:/content
Content-Type: application/octet-stream
[binary file content]
For files over 4 MB, use the createUploadSession endpoint to chunk the upload (supports files up to 250 GB). Microsoft's SharePoint Migration API recommends keeping import packages under 250 MB or 250 items for optimal performance and supports individual files up to 15 GB. The Migration API uses Azure Blob Storage as a staging ground, allowing you to batch-upload attachments efficiently before attaching them to Lists or Pages. (learn.microsoft.com)
The Image Column Workaround
SharePoint's Image column type stores images as serialized JSON metadata pointing to files in a hidden SiteAssets library. Writing to this column programmatically via Graph API requires a three-step process: upload the image to the site's drive, get the webUrl and serverRelativeUrl from the response, then construct a JSON string for the Image column value. This is poorly documented by Microsoft — expect trial and error.
List Item Attachments
If you need attachments on SharePoint list items specifically, the Graph API does not expose a direct endpoint for list-item attachments. You must use the SharePoint REST API's AttachmentFiles endpoint instead. For most migrations, a Document Library with rewritten links is the cleaner model. (learn.microsoft.com)
For more on how to structure files and metadata in SharePoint, see SharePoint Information Architecture: Content Types, Metadata & Lists.
Post-Migration Validation Checklist
After migrating, verify these before decommissioning your Coda workspace:
- Row count match: Compare Coda table row counts to SharePoint List item counts
- Column type verification: Spot-check 10% of columns for correct data types (dates, numbers, choice values)
- Lookup integrity: Verify Lookup columns resolve to the correct target list items
- Image rendering: Open 10 random Site Pages and confirm all images load
- Attachment access: Download 5 random attachments from the Document Library and verify they open correctly
- Formula/calculated columns: Verify computed values match Coda source
- Permissions: Confirm SharePoint permissions match your intended access model (Coda permissions do not transfer)
- Search indexing: Verify migrated content appears in SharePoint search within 24–48 hours
- View threshold compliance: Confirm all views on lists with 5,000+ items have indexed columns and filtered views
- Internal links: Verify all rewritten URLs resolve to the correct SharePoint pages and files
Keep Coda read-only for 30 days post-migration. Don't delete your Coda workspace immediately. Users will discover missing content, broken references, or edge cases that need patching. A 30-day parallel operation window is standard practice.
Keep a migration manifest with these fields: source object ID, source URL, target object ID, target URL, checksum, row count, attachment count, validation status, and retry status. That single file saves hours when QA surfaces edge cases.
Common Failure Modes
1. Hitting the 125 MB API wall mid-extraction The doc grew past 125 MB between your test extraction and the production run. The API returns an error on a doc that was previously accessible. Fix: Monitor doc size before migration day. Split large docs proactively.
2. SharePoint List View Threshold errors after import "The number of items in this list exceeds the list view threshold" appears immediately after bulk import. Fix: Create column indexes before importing data, not after. Index the columns used in your default view.
3. Broken images on migrated Site Pages Images show as broken links because they still point to Coda CDN URLs that have expired. Fix: Build an image extraction and relinking step into your pipeline. Never leave Coda CDN URLs in migrated content.
4. Lookup columns pointing to nonexistent lists SharePoint rejects list item creation because a Lookup column references a List that hasn't been created yet. Fix: Use topological sorting — create target lists (those referenced by lookups) before source lists.
5. Silent data truncation on wide text fields Long text values from Coda are cut off in SharePoint Single Line of Text columns (255-character limit). Fix: Map any Coda text column with values longer than 255 characters to SharePoint's "Multiple lines of text" type.
6. People and Lookup columns blank after import
You loaded rows before the target lists existed or before resolving user identities to Entra ID.
Fix: Load parent lists first, resolve users to UPNs before patching Person fields, and test the LookupId pattern on a staging list. (learn.microsoft.com)
7. SharePoint page creation fails or pages render incorrectly You tried to use an unsupported web part type in the Graph API call. Fix: Check the supported web part list in Microsoft's documentation. The page API only accepts a defined set — everything else must drop to text, image, or manual rebuild. (learn.microsoft.com)
How ClonePartner Handles the Hard Parts
The Coda-to-SharePoint migration is one of the more technically demanding paths we see — specifically because it requires decomposing a unified document model into three separate SharePoint structures while preserving relationships between them.
What our managed migration handles that manual and iPaaS approaches don't:
- Coda's 125 MB API limit: Automated doc analysis and splitting before extraction begins
- Rate limit management: Intelligent queueing with exponential backoff across all Coda API rate constraints
- Canvas page conversion: Parsing Coda's proprietary page format and mapping it to SharePoint Site Page Web Part structures via the Graph API
- Relational integrity: Topological sort of table dependencies to preserve Lookup column relationships across SharePoint Lists
- Attachment relinking: Automated extraction from Coda CDN, upload to Document Libraries, and URL rewriting across all migrated content
- Author and timestamp preservation: Original metadata stored in explicit columns with full audit trail
- Zero downtime: Your Coda workspace stays live and readable throughout
We've completed 1,200+ migrations across dozens of platforms. If your workspace has more than 20 tables, rich canvas pages, or cross-table lookups, the API engineering alone can consume weeks. We typically complete these in days.
Frequently Asked Questions
- Can I directly migrate from Coda to SharePoint?
- No. There is no native migration path, connector, or importer between Coda and SharePoint. You must export data via Coda's API or CSV exports, transform it, and import it into SharePoint using the Microsoft Graph API, manual import, or a migration service.
- What is the Coda API size limit for migration?
- Coda docs at or above 125 MB (excluding attachments) are completely blocked from API access. The API will refuse all requests. You must split large docs below 125 MB before automated extraction can proceed. Rate limits are 100 reads per 6 seconds and 10 writes per 6 seconds per user.
- How do I handle SharePoint's 5,000-item list view threshold after importing Coda data?
- The 5,000-item threshold is a query throttle, not a storage limit. Before importing data, create column indexes on the fields you'll filter and sort by (up to 20 per list). Create filtered views that return fewer than 5,000 items. Import data in batches via the Graph API rather than a single CSV dump.
- Can I migrate Coda canvas pages to SharePoint Site Pages?
- Partially. Coda canvas pages must be parsed from their proprietary format, converted to HTML, and reconstructed as SharePoint Site Pages using the Graph API's canvasLayout with Web Parts. Headings and basic formatting transfer well, but embedded tables, buttons, @mentions, and toggle sections are lost or require manual rebuild.
- How do Coda table column types map to SharePoint List columns?
- Most types have equivalents: Text → Single line of text, Number → Number, Checkbox → Yes/No, Select → Choice, Date → DateTime, Person → Person or Group (requires Entra ID lookup). Lookups map to SharePoint Lookup columns but target lists must exist first. Formulas, buttons, and automations have no direct equivalent and must be rebuilt.