Back to API Reference

Google Sheets API

Connect Google Sheets as live data sources for document generation and email campaigns. OAuth2 integration with automatic token refresh.

---

Base URL

https://app.datapublisher.io/api/google

---

Authentication

All endpoints require JWT authentication via Authorization: Bearer header.

---

Overview

The Google Sheets API allows you to:

Supported Google APIs:

Required Scopes:

---

OAuth2 Connection Flow

Step 1: Start Authorization

Initiate Google OAuth2 flow to connect Google Sheets.

Endpoint: GET /auth/start

Headers:

Authorization: Bearer 

Response (200 OK):

{

"success": true,

"authUrl": "https://accounts.google.com/o/oauth2/v2/auth?client_id=...&redirect_uri=...&response_type=code&scope=...&state=xyz789",

"message": "Redirect user to this URL to authorize Google Sheets access"

}

Usage:

  • Get authUrl from this endpoint
  • Redirect user to authUrl (open in browser dialog)
  • User signs into Google
  • User grants spreadsheet access
  • Google redirects to callback URL
  • ---

    Step 2: OAuth2 Callback (Automatic)

    Google automatically redirects here after authorization. DataPublisher handles this internally.

    Endpoint: GET /auth/callback

    Process:

  • Receives authorization code from Google
  • Validates state parameter (CSRF protection)
  • Exchanges code for access + refresh tokens
  • Retrieves user's Google account email
  • Encrypts and stores tokens in database
  • Shows success page that auto-closes
  • Stored Data:

    data_sources table:
    
    • UserId: User UUID
    • Name: Google account email
    • Type: 'google_sheets'
    • IsActive: true

    api_credentials table:

    • UserId: User UUID
    • DataSourceId: Reference to data source
    • CredentialType: 'google_oauth2'
    • EncryptedCredentials: AES-256 encrypted tokens
    • TokenExpiry: Token expiration timestamp

    ---

    Spreadsheet Operations

    List Spreadsheets

    Get all Google Sheets files accessible to the connected account.

    Endpoint: GET /spreadsheets

    Headers:

    Authorization: Bearer 

    Response (200 OK):

    {
    

    "success": true,

    "spreadsheets": [

    {

    "id": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms",

    "name": "Customer Database",

    "url": "https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms",

    "createdTime": "2026-01-15T10:00:00Z",

    "modifiedTime": "2026-02-12T09:30:00Z",

    "owner": "user@gmail.com"

    },

    {

    "id": "1Ab2Cd3Ef4Gh5Ij6Kl7Mn8Op9Qr0St",

    "name": "Sales Report 2026",

    "url": "https://docs.google.com/spreadsheets/d/1Ab2Cd3Ef4Gh5Ij6Kl7Mn8Op9Qr0St",

    "createdTime": "2026-02-01T08:00:00Z",

    "modifiedTime": "2026-02-12T10:15:00Z",

    "owner": "team@company.com"

    }

    ],

    "count": 2

    }

    Query Parameters:

    ---

    Get Spreadsheet Metadata

    Retrieve detailed information about a specific spreadsheet.

    Endpoint: GET /spreadsheets/:spreadsheetId

    Headers:

    Authorization: Bearer 

    Path Parameters:

    Response (200 OK):

    {
    

    "success": true,

    "spreadsheet": {

    "id": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms",

    "name": "Customer Database",

    "url": "https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms",

    "sheets": [

    {

    "sheetId": 0,

    "title": "Customers",

    "index": 0,

    "rowCount": 1500,

    "columnCount": 12

    },

    {

    "sheetId": 1,

    "title": "Orders",

    "index": 1,

    "rowCount": 3200,

    "columnCount": 8

    }

    ],

    "locale": "en_US",

    "timeZone": "America/New_York"

    }

    }

    ---

    Get Sheet Data

    Retrieve data from a specific sheet within a spreadsheet.

    Endpoint: GET /spreadsheets/:spreadsheetId/sheets/:sheetName/data

    Headers:

    Authorization: Bearer 

    Path Parameters:

    Query Parameters:

    Response (200 OK):

    {
    

    "success": true,

    "spreadsheetId": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms",

    "sheetName": "Customers",

    "range": "A1:L1500",

    "headers": [

    "CustomerID",

    "CompanyName",

    "ContactName",

    "Email",

    "Phone",

    "Address",

    "City",

    "State",

    "ZipCode",

    "Country",

    "TotalSales",

    "SignupDate"

    ],

    "data": [

    {

    "CustomerID": "1001",

    "CompanyName": "Acme Corp",

    "ContactName": "John Doe",

    "Email": "john@acme.com",

    "Phone": "555-0100",

    "Address": "123 Main St",

    "City": "New York",

    "State": "NY",

    "ZipCode": "10001",

    "Country": "USA",

    "TotalSales": "45000",

    "SignupDate": "2025-06-15"

    }

    ],

    "rowCount": 1500,

    "columnCount": 12

    }

    ---

    Import Sheet to CSV

    Import Google Sheet data as a CSV file in DataPublisher.

    Endpoint: POST /spreadsheets/:spreadsheetId/sheets/:sheetName/import

    Headers:

    Authorization: Bearer 
    

    Content-Type: application/json

    Path Parameters:

    Request Body:

    {
    

    "fileName": "customer-data.csv",

    "description": "Imported from Google Sheets",

    "tags": ["customers", "google-sheets"],

    "range": "A1:L1500"

    }

    Response (200 OK):

    {
    

    "success": true,

    "fileId": "csv-file-uuid",

    "fileName": "customer-data.csv",

    "rowCount": 1499,

    "columnCount": 12,

    "message": "Google Sheet imported successfully"

    }

    Notes:

    ---

    Connection Management

    Get Connection Status

    Check if Google Sheets is connected and token status.

    Endpoint: GET /connection/status

    Headers:

    Authorization: Bearer 

    Response (200 OK):

    {
    

    "success": true,

    "connected": true,

    "email": "user@gmail.com",

    "tokenExpiresAt": "2026-02-13T10:00:00Z",

    "daysUntilExpiry": 30,

    "connectedAt": "2026-01-15T09:00:00Z"

    }

    OR if not connected:

    {
    

    "success": true,

    "connected": false,

    "message": "Google Sheets not connected"

    }

    ---

    Disconnect Google Sheets

    Remove Google Sheets connection and delete stored tokens.

    Endpoint: DELETE /connection

    Headers:

    Authorization: Bearer 

    Response (200 OK):

    {
    

    "success": true,

    "message": "Google Sheets disconnected successfully"

    }

    Notes:

    ---

    Extracting Spreadsheet ID from URL

    Google Sheets URL format:

    https://docs.google.com/spreadsheets/d/SPREADSHEET_ID/edit?gid=SHEET_ID

    Example:

    URL: https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit
    

    Spreadsheet ID: 1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms

    ---

    Token Management

    Automatic Token Refresh

    Access tokens expire after 1 hour. DataPublisher automatically refreshes them using the refresh token.

    Process:

  • Before API call, check if token expired
  • If expired, call Google OAuth token endpoint with refresh_token
  • Get new access_token
  • Update database with new token
  • Proceed with original API call
  • No manual intervention needed!

    ---

    Rate Limiting

    ---

    Common Error Codes

    | Status Code | Description |

    |-------------|-------------|

    | 400 | Invalid spreadsheet ID or sheet name |

    | 401 | Unauthorized - not connected or token expired |

    | 403 | Google API access denied (insufficient permissions) |

    | 404 | Spreadsheet or sheet not found |

    | 429 | Rate limit exceeded (Google API) |

    | 500 | Google API error or internal server error |

    ---

    Usage Examples

    JavaScript (Office Add-in)

    // Connect Google Sheets
    

    async function connectGoogleSheets() {

    const response = await fetch('https://app.datapublisher.io/api/google/auth/start', {

    headers: {

    'Authorization': Bearer ${jwtToken}

    }

    });

    const { authUrl } = await response.json();

    // Open OAuth dialog

    window.open(authUrl, '_blank', 'width=600,height=700');

    }

    // List spreadsheets

    async function listSpreadsheets() {

    const response = await fetch('https://app.datapublisher.io/api/google/spreadsheets', {

    headers: {

    'Authorization': Bearer ${jwtToken}

    }

    });

    const { spreadsheets } = await response.json();

    console.log('Spreadsheets:', spreadsheets);

    }

    // Get sheet data

    async function getSheetData(spreadsheetId, sheetName) {

    const response = await fetch(

    https://app.datapublisher.io/api/google/spreadsheets/${spreadsheetId}/sheets/${encodeURIComponent(sheetName)}/data,

    {

    headers: {

    'Authorization': Bearer ${jwtToken}

    }

    }

    );

    const data = await response.json();

    console.log('Sheet data:', data);

    return data;

    }

    // Import sheet as CSV

    async function importSheet(spreadsheetId, sheetName) {

    const response = await fetch(

    https://app.datapublisher.io/api/google/spreadsheets/${spreadsheetId}/sheets/${encodeURIComponent(sheetName)}/import,

    {

    method: 'POST',

    headers: {

    'Authorization': Bearer ${jwtToken},

    'Content-Type': 'application/json'

    },

    body: JSON.stringify({

    fileName: ${sheetName}.csv,

    description: 'Imported from Google Sheets',

    tags: ['google-sheets']

    })

    }

    );

    const result = await response.json();

    console.log('Import result:', result);

    return result.fileId;

    }

    Python (requests)

    import requests
    
    

    API_URL = 'https://app.datapublisher.io/api/google'

    headers = {'Authorization': f'Bearer {jwt_token}'}

    Get spreadsheets

    response = requests.get(f'{API_URL}/spreadsheets', headers=headers)

    spreadsheets = response.json()['spreadsheets']

    Get sheet data

    spreadsheet_id = '1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms'

    sheet_name = 'Customers'

    response = requests.get(

    f'{API_URL}/spreadsheets/{spreadsheet_id}/sheets/{sheet_name}/data',

    headers=headers

    )

    data = response.json()

    print(f"Retrieved {data['rowCount']} rows")

    Import as CSV

    response = requests.post(

    f'{API_URL}/spreadsheets/{spreadsheet_id}/sheets/{sheet_name}/import',

    json={

    'fileName': 'customers.csv',

    'description': 'Customer data from Google Sheets'

    },

    headers=headers

    )

    file_id = response.json()['fileId']

    print(f"Imported as file ID: {file_id}")

    ---

    Best Practices

  • Token Refresh: Tokens auto-refresh - no manual action needed
  • Rate Limits: Cache frequently accessed data to avoid API limits
  • Sheet Names: URL-encode sheet names with spaces
  • Large Sheets: Use limit and offset for pagination
  • Data Types: All data returned as strings - convert as needed
  • Error Handling: Handle 401 errors by prompting reconnection
  • Permissions: Ensure user has read access to requested sheets
  • ---

    Related Documentation