What You'll Build

A fully functional contact form that saves submissions directly to your Google Sheet. No server, no database, no backend code required.

Step 1: Create Your Google Sheet

Create a new Google Sheet with these column headers:

  • Name - Visitor's name
  • Email - Visitor's email address
  • Message - The contact message
  • Date - Timestamp of submission

Make your sheet public (Anyone with the link can view) and copy the Sheet ID from the URL.

Step 2: Connect to SheetAPI.pro

Sign up for a free account and add your Google Sheet. You'll get an API key to authenticate your requests.

Step 3: Add the HTML Form

Use the HTML code from the snippets panel to create your contact form. It includes basic styling and form validation.

Step 4: Handle Form Submissions

The JavaScript code intercepts form submissions and sends the data to your Google Sheet via the API. It includes error handling and user feedback.

Step 5: Test & Deploy

Replace YOUR_SHEET_ID and YOUR_API_KEY with your actual values. Test the form and deploy to any static hosting (GitHub Pages, Netlify, Vercel).

Use Cases

  • Landing pages - Collect leads without backend infrastructure
  • Portfolio sites - Simple contact form for freelancers
  • Small businesses - Customer inquiries directly to your Sheet
  • Event pages - Quick contact collection for events

Next Steps

  • Add email notifications when new submissions arrive
  • Set up webhooks to trigger actions on form submit
  • Integrate with other tools (Zapier, Make, n8n)
  • Add reCAPTCHA to prevent spam
HTML
JavaScript
Python
PHP
cURL
<!DOCTYPE html>
<html>
<head>
    <title>Contact Form</title>
    <style>
        body { font-family: Arial, sans-serif; max-width: 500px; margin: 50px auto; }
        input, textarea { width: 100%; padding: 10px; margin: 10px 0; border: 1px solid #ddd; border-radius: 4px; }
        button { background: #667eea; color: white; padding: 12px 30px; border: none; border-radius: 4px; cursor: pointer; }
        button:hover { background: #5568d3; }
        .success { color: green; margin-top: 10px; }
    </style>
</head>
<body>
    <h2>Contact Us</h2>
    <form id="contactForm">
        <input type="text" name="name" placeholder="Your Name" required>
        <input type="email" name="email" placeholder="Your Email" required>
        <textarea name="message" placeholder="Your Message" rows="5" required></textarea>
        <button type="submit">Send Message</button>
    </form>
    <div id="status"></div>
    <script src="script.js"></script>
</body>
</html>
document.getElementById('contactForm').addEventListener('submit', async (e) => {
    e.preventDefault();
    
    const formData = new FormData(e.target);
    const data = {
        Name: formData.get('name'),
        Email: formData.get('email'),
        Message: formData.get('message'),
        Date: new Date().toISOString()
    };
    
    try {
        const response = await fetch('https://sheetapi.pro/api/v1/sheets/{SHEET_ID}/data', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': 'Bearer YOUR_API_KEY'
            },
            body: JSON.stringify(data)
        });
        
        if (response.ok) {
            document.getElementById('status').innerHTML = 
                '<div class="success">✓ Message sent successfully!</div>';
            e.target.reset();
        } else {
            throw new Error('Failed to send');
        }
    } catch (error) {
        document.getElementById('status').innerHTML = 
            '<div style="color:red">✗ Failed to send. Please try again.</div>';
    }
});
from flask import Flask, request, jsonify
import requests
from datetime import datetime

app = Flask(__name__)

SHEET_ID = 'YOUR_SHEET_ID'
API_KEY = 'YOUR_API_KEY'
API_URL = f'https://sheetapi.pro/api/v1/sheets/{SHEET_ID}/data'

@app.route('/contact', methods=['POST'])
def contact():
    data = request.json
    
    payload = {
        'Name': data.get('name'),
        'Email': data.get('email'),
        'Message': data.get('message'),
        'Date': datetime.now().isoformat()
    }
    
    headers = {
        'Content-Type': 'application/json',
        'Authorization': f'Bearer {API_KEY}'
    }
    
    response = requests.post(API_URL, json=payload, headers=headers)
    
    if response.status_code == 200:
        return jsonify({'success': True, 'message': 'Contact saved'})
    else:
        return jsonify({'success': False, 'error': 'Failed to save'}), 500

if __name__ == '__main__':
    app.run(debug=True)
<?php
// contact-handler.php
header('Content-Type: application/json');

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $data = json_decode(file_get_contents('php://input'), true);
    
    $payload = [
        'Name' => $data['name'],
        'Email' => $data['email'],
        'Message' => $data['message'],
        'Date' => date('c')
    ];
    
    $ch = curl_init('https://sheetapi.pro/api/v1/sheets/YOUR_SHEET_ID/data');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Content-Type: application/json',
        'Authorization: Bearer YOUR_API_KEY'
    ]);
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    if ($httpCode === 200) {
        echo json_encode(['success' => true]);
    } else {
        http_response_code(500);
        echo json_encode(['success' => false, 'error' => 'Failed to save']);
    }
}
?>
# Send a contact form submission
curl -X POST https://sheetapi.pro/api/v1/sheets/YOUR_SHEET_ID/data \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "Name": "John Doe",
    "Email": "john@example.com",
    "Message": "Hello, I would like to get in touch!",
    "Date": "2024-01-15T10:30:00Z"
  }'

# Read all submissions
curl -X GET https://sheetapi.pro/api/v1/sheets/YOUR_SHEET_ID/data \
  -H "Authorization: Bearer YOUR_API_KEY"