Overview
This article provides examples of common SODA2 query patterns and their SODA3 equivalents. Whether you're building integrations, performing data analysis, or exploring public datasets, these examples will help you understand when and how to use SODA3.
For a conceptual overview of SODA3 and why it was introduced, see Introducing the new SODA3 API.
SODA3 is the recommended API for all new integrations. SODA2 remains supported and no deprecation date has been announced, but we recommend converting SODA2 integrations to SODA3 as you update them.
Coming from SODA1? SODA1 (/views/{4x4}/rows, /api/views/{4x4}/rows) is deprecated as of 10/7/2026 and will be permanently removed on 12/16/2026. See SODA1 Migration below.
What is SODA3
The new SODA3 API is designed to make working with your data simpler and more reliable. With improved performance, smarter caching, and clearer error handling, it's now easier than ever to build exactly what you need. For more technical details you can check our dev site, https://dev.socrata.com/docs/endpoints
Here's what you'll notice right away:
Improved Performance - Our updated query endpoint provides the best performance and clearer error handling especially for complex queries.
Cleaner queries – No more stitching together "$" parameters. You can now write straightforward SoQL queries or send larger requests as a JSON payload.
Simplified results – Paging and limits are easier to manage directly within your query, reducing complexity.
Clearer identification – Every request now shows who is making the call, helping the system better support your use case and deliver more consistent results.
Understanding SODA3 Endpoints
SODA3 introduces two primary endpoints:
Query Endpoint: /api/v3/views/{id}/query.{format}
Purpose: Machine-readable responses for application integration
Formats: JSON, CJSON, NDJSON (newline-delimited), GeoJSON, CSV, TSV, XML
Methods: GET (with ?query= parameter and full query syntax) or POST (with JSON body)
Use cases: Building applications, dashboards, integrations
Authentication: Required (app token or user credentials)
Important Note: SODA3 does not support the fragmented query syntax from SODA2 (separate $where, $select, $limit parameters). Instead, write complete SoQL queries using the ?query= parameter or POST a JSON body with a query field.
Export Endpoint: /api/v3/views/{id}/export.{format}
Purpose: Human-readable data exports in various formats
Formats: CSV, TSV, XLSX, KML, KMZ
Methods: GET
Use cases: Downloading datasets, generating reports
Authentication: Required for filtered exports; not required for full public dataset exports
When to Use Each Endpoint
| Use Case | Endpoint | Method | Auth Required |
Download full public dataset as CSV |
Export | GET | No |
Download filtered dataset for reporting |
Export | GET | Yes |
Build an integration |
Query | POST | Yes |
Quick API test in browser |
Query | GET | Yes |
Aggregation queries (count, sum) |
Query | POST | Yes |
Complex queries |
Query | POST | Yes |
Authentication and App Tokens
Full exports via /api/v3/views/{id}/export do not require authentication for public datasets.
Filtered exports or query endpoints require authentication:
Include an app token: $$app_token=YOUR_TOKEN or X-App-Token header
Or use OAuth authentication
Register for an app token to get started.
Pagination: SODA3 vs SODA2
SODA2 used explicit $limit and $offset parameters.
SODA3 improves pagination by automatically imposing a total order on results.
Using SODA3 Pagination (POST)
POST /api/v3/views/{id}/query.json
{
"query": "SELECT * WHERE status='active'",
"page": {
"pageSize": 1000,
"pageNumber": 1
}
}Increment pageNumber for subsequent pages (1, 2, 3...).
Best Practice: Keyset Pagination
For the most efficient pagination, use keyset pagination instead:
SELECT * WHERE primary_key > 'last_value' ORDER BY primary_key LIMIT 1000This approach is:
Faster than offset-based pagination
More efficient on large datasets
Recommendation: Use SODA3's built-in pagination when you cannot use keyset pagination. For high-performance applications, use keyset pagination when possible.
Examples
Example 1: Full Dataset Export
Use Case: Download complete dataset as CSV for offline analysis
SODA2:
GET /resource/abc-1234.csvSODA3:
GET /api/v3/views/abc-1234/export.csvAuth: Not required for public datasets
Example 2: Filtered Export
Use Case: Download subset of records for reporting
SODA2:
GET /resource/abc-1234.csv?$where=state_code='NY'&$limit=1000SODA3:
GET /api/v3/views/abc-1234/export.csv?query=SELECT * WHERE state_code='NY' LIMIT 1000Auth: Required
Note: SODA3 requires complete SoQL queries in the ?query= parameter, not fragmented $where, $limit parameters.
Example 3: Simple Query with GET
Use Case: Quick API test to retrieve specific records
SODA2:
GET /resource/abc-1234.json?$where=property_type='PA'&$limit=1SODA3:
GET /api/v3/views/abc-1234/query.json?query=SELECT * WHERE property_type='PA' LIMIT 1Auth: Required
Example 4: Query with POST
Use Case: Application integration for filtered data
SODA2:
GET /resource/abc-1234.json?$where=state_code='CA'&$limit=10SODA3:
POST /api/v3/views/abc-1234/query.json
Content-Type: application/json
{
"query": "SELECT * WHERE state_code='CA' LIMIT 10"
}Auth: Required
Best Practice: Use POST for production applications - it allows longer queries.
Example 5: Date Range Filtering
Use Case: Daily report for specific date range
SODA2:
GET /resource/abc-1234.json?$where=date>='2026-07-12T00:00:00' AND date<='2026-07-12T23:59:59'&$order=date ASC&$limit=1000SODA3:
POST /api/v3/views/abc-1234/query.json
{
"query": "SELECT * WHERE date >= '2026-07-12T00:00:00' AND date <= '2026-07-12T23:59:59' ORDER BY date ASC LIMIT 1000"
}Auth: Required
Example 6: Aggregation - Count
Use Case: Get total record count without downloading data
SODA2:
GET /resource/abc-1234.json?$select=count(*) as cSODA3:
POST /api/v3/views/abc-1234/query.json
{
"query": "SELECT count(*) as c"
}Auth: Required
Example 7: Ordering and Pagination
Use Case: Get most recent records with pagination
SODA2:
GET /resource/abc-1234.json?$order=:id DESC&$limit=50&$offset=0
GET /resource/abc-1234.json?$order=:id DESC&$limit=50&$offset=50SODA3:
POST /api/v3/views/abc-1234/query.json
{
"query": "SELECT * ORDER BY :id DESC",
"page": {
"pageSize": 50,
"pageNumber": 1
}
}Then increment pageNumber for subsequent pages.
Auth: Required
Example 8: Complex Query with Multiple Clauses
Use Case: Filtered query with specific columns, filtering, and sorting
SODA2:
GET /resource/abc-1234.json?$select=report_date,market_name,open_interest&$where=market_name like 'EURO FX%'&$order=report_date DESC&$limit=20SODA3:
POST /api/v3/views/abc-1234/query.json
{
"query": "SELECT report_date, market_name, open_interest WHERE market_name like 'EURO FX%' ORDER BY report_date DESC LIMIT 20"
}Auth: Required
Best Practices Summary
Use export for downloads - Use /export endpoint when downloading datasets as files (CSV, Excel, etc.)
Use query for integrations - Use /query endpoint when building applications that consume JSON data
Prefer POST for queries - POST method recommended for production applications
Write complete SoQL queries - SODA3 doesn't support fragmented syntax ($where, $select, $limit as separate parameters)
Consider keyset pagination for performance - WHERE primary_key > last_value ORDER BY primary_key is faster
Choose the right CSV endpoint - Use /query.csv for machine processing which has a standard format across datasets and views, /export.csv for human-readable report which honors the views formatting.
SODA1 Migration
Identify Your API Version
Locate the Data & Insights API URL in use, potentially saved in your integration, and compare it with these patterns:
If your URL ends in rows, this is a SODA1 endpoint
If your URL contains /resource/ or /id/, this is a SODA2 endpoint
If your URL contains /v3/, this is a SODA3 endpoint
Reads: Migrate SODA1 read integrations directly to SODA3; there is no need to go through SODA2 first. Replace /views/{dataset-id}/rows and /api/views/{dataset-id}/rows with the SODA3 query or export endpoint.
Full download, SODA1:
GET /api/views/abc-1234/rows.csv?accessType=DOWNLOADSODA3:
GET /api/v3/views/abc-1234/export.csvJSON rows, SODA1:
GET /api/views/abc-1234/rows.jsonSODA3:
POST /api/v3/views/abc-1234/query.json
{
"query": "SELECT *",
"page": {
"pageSize": 1000,
"pageNumber": 1
}
}Finding SODA1 calls: Search integration code, configuration, and request logs for URLs containing /views/ followed by /rows. This includes integrations managed by other teams or vendors, which may need to be notified.
Comments
Article is closed for comments.