Skip to main content
Flip a coin — embed and API integration example

Embed API & Bulk Coin Flips for Developers

By FlipACoinFree Dev Team15 min read

Adding randomization features to your website or application doesn't have to be complicated. Whether you're building a giveaway platform, creating educational tools, developing games, or need fair decision-making in your app, integrating a reliable coin flip system can solve many problems. This guide shows you exactly how to embed our coin flip widget or integrate our API—written by developers who have implemented these solutions hundreds of times.

After helping thousands of developers integrate coin flip functionality into their projects, we've learned what works and what doesn't. This isn't a generic API tutorial—it's a practical guide based on real implementation experience, complete with working code examples you can copy and paste.

Simple Integration

2-minute setup with iframe or full control with JavaScript SDK

Fast & Reliable

99.9% uptime with sub-100ms response times globally

Cryptographically Secure

CSPRNG algorithm with verifiable randomness

Quick Start: Embed Widget Integration

The fastest way to add coin flip functionality to your website is using our embed widget. No coding required—just copy and paste. This method works perfectly for blogs, landing pages, event sites, and anywhere you need a simple, visual coin flip interface.

Method 1: Basic iframe Embed (2 Minutes)

Copy this code and paste it anywhere in your HTML where you want the coin flip to appear:

<!-- Basic embed - default settings -->
<iframe 
  src="https://flipacoinfree.com/widget" 
  width="400" 
  height="500" 
  frameborder="0"
  title="Coin Flip Widget"
></iframe>

That's it. The widget will work immediately with sound effects, animations, and full mobile responsiveness. It automatically adjusts to your site's theme (light or dark mode).

Method 2: Customized Embed with Parameters

Want more control? Add URL parameters to customize appearance and behavior:

<!-- Customized embed with options -->
<iframe 
  src="https://flipacoinfree.com/widget?theme=dark&sound=off&autoflip=true" 
  width="400" 
  height="500" 
  frameborder="0"
  title="Custom Coin Flip"
></iframe>

Available Parameters:

  • theme - Set to "light" or "dark" (default: auto-detect)
  • sound - Set to "on" or "off" (default: on)
  • autoflip - Set to "true" to flip on page load (default: false)
  • language - Set to "en", "es", "fr", "de" (default: en)

Method 3: JavaScript SDK (Advanced)

For developers who need programmatic control, our JavaScript SDK provides full access to flip events, custom styling, and integration with your application state:

<!-- Add SDK to your HTML -->
<script src="https://flipacoinfree.com/sdk.js"></script>
<div id="coin-flip-container"></div>

<script>
  // Initialize the widget
  const coinFlip = new FlipACoinFree({
    container: '#coin-flip-container',
    theme: 'dark',
    onFlip: (result) => {
      console.log('Flip result:', result); // 'heads' or 'tails'
      // Your custom logic here
    },
    onComplete: (result) => {
      // Called when animation finishes
      saveResultToDatabase(result);
    }
  });

  // Programmatically trigger a flip
  document.getElementById('myButton').addEventListener('click', () => {
    coinFlip.flip();
  });
</script>

The SDK gives you event callbacks, custom button integration, and the ability to trigger flips from your own UI. Perfect for games, interactive tutorials, and custom user experiences.

API Basics and Authentication

Our REST API allows you to integrate coin flips directly into your backend services, mobile apps, or any system that can make HTTP requests. The API is free for personal and commercial use with reasonable rate limits.

Base URL and Endpoints

All API requests use the base URL: https://flipacoinfree.com/api

EndpointMethodPurpose
/api/flipGET/POSTSingle coin flip
/api/batchflipPOSTMultiple flips (bulk operation)
/api/statsGETGlobal statistics

Authentication (Optional)

Basic API usage requires no authentication. For higher rate limits and premium features, you can include an API key in the request header:

// With API key (optional)
fetch('https://flipacoinfree.com/api/flip', {
  headers: {
    'X-API-Key': 'your-api-key-here'
  }
})

Rate Limits

  • Free tier: 100 requests per minute, 10,000 per day
  • With API key: 1,000 requests per minute, 100,000 per day
  • Enterprise: Custom limits available

Rate limit headers are included in every response so you can monitor your usage programmatically.

Single Flip API Endpoint

The /api/flip endpoint returns a single coin flip result. This is perfect for simple decision-making, user interactions, or when you need one random binary outcome.

Example Request

// JavaScript fetch example
fetch('https://flipacoinfree.com/api/flip')
  .then(response => response.json())
  .then(data => {
    console.log('Result:', data.result);
    console.log('Timestamp:', data.timestamp);
  });

// Example response
{
  "result": "heads",
  "timestamp": "2025-01-30T14:23:45.123Z",
  "hash": "a7f3c9d2e8b1f6a4",
  "session_id": "sess_abc123"
}

Response Fields Explained

  • result: Either "heads" or "tails"
  • timestamp: ISO 8601 timestamp of when the flip occurred
  • hash: Cryptographic hash for verification purposes
  • session_id: Unique identifier for tracking (useful for audits)

Real-World Use Cases

Here are practical examples from developers who use this endpoint:

Use Case: Random User Selection for Beta Testing

// Select users randomly for A/B test
async function assignBetaAccess(userId) {
  const flip = await fetch('https://flipacoinfree.com/api/flip')
    .then(r => r.json());
  
  if (flip.result === 'heads') {
    await database.updateUser(userId, { betaAccess: true });
    return 'You're in the beta!';
  }
  return 'Stay tuned for next round';
}

Use Case: Randomize Content Display

// Show different hero section randomly
const flip = await fetch('https://flipacoinfree.com/api/flip')
  .then(r => r.json());

const heroVariant = flip.result === 'heads' ? 'variant-a' : 'variant-b';
renderHero(heroVariant);

Bulk Flip Operations for Scale

Need to run hundreds or thousands of flips at once? The /api/batchflip endpoint is designed for high-volume operations like giveaways, statistical analysis, simulations, and large contests.

Basic Bulk Flip Request

// Request 1000 flips
fetch('https://flipacoinfree.com/api/batchflip', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    count: 1000,
    format: 'summary' // or 'detailed'
  })
})
.then(response => response.json())
.then(data => {
  console.log('Heads:', data.heads);
  console.log('Tails:', data.tails);
  console.log('Distribution:', data.distribution);
});

// Example response (summary format)
{
  "count": 1000,
  "heads": 503,
  "tails": 497,
  "distribution": "50.3% heads, 49.7% tails",
  "session_id": "batch_xyz789",
  "timestamp": "2025-01-30T14:30:00.000Z",
  "execution_time_ms": 45
}

Detailed Results Format

For audit trails and record-keeping, use format: 'detailed' to get every individual flip result:

// Detailed format request
{
  "count": 100,
  "format": "detailed"
}

// Response includes array of all results
{
  "count": 100,
  "results": [
    { "flip": 1, "result": "heads", "timestamp": "..." },
    { "flip": 2, "result": "tails", "timestamp": "..." },
    // ... 98 more
  ],
  "summary": {
    "heads": 52,
    "tails": 48
  },
  "session_id": "batch_xyz789"
}

Real Example: Giveaway System

Here's how one developer built a fair giveaway system using our bulk flip API:

async function runGiveaway(participants) {
  // Each participant gets one flip
  const response = await fetch('https://flipacoinfree.com/api/batchflip', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      count: participants.length,
      format: 'detailed'
    })
  });

  const data = await response.json();
  
  // Match participants with flip results
  const winners = participants.filter((participant, index) => {
    return data.results[index].result === 'heads';
  });

  // Save to database for audit trail
  await database.saveGiveaway({
    sessionId: data.session_id,
    participants: participants.length,
    winners: winners.length,
    timestamp: data.timestamp
  });

  return winners;
}

Export Results as CSV

For transparency and record-keeping, you can easily convert bulk flip results to CSV format:

function exportToCSV(batchResults) {
  const csv = ['Flip Number,Result,Timestamp'];
  
  batchResults.results.forEach((flip, index) => {
    csv.push(`${index + 1},${flip.result},${flip.timestamp}`);
  });

  const blob = new Blob([csv.join('\n')], { type: 'text/csv' });
  const url = URL.createObjectURL(blob);
  
  // Trigger download
  const a = document.createElement('a');
  a.href = url;
  a.download = `giveaway-${batchResults.session_id}.csv`;
  a.click();
}

Real-World Code Examples

Here are complete, copy-paste-ready examples in multiple programming languages based on actual implementations from our developer community.

JavaScript / Node.js Example

// Complete Node.js example with error handling
const https = require('https');

async function flipCoin() {
  return new Promise((resolve, reject) => {
    https.get('https://flipacoinfree.com/api/flip', (res) => {
      let data = '';
      
      res.on('data', (chunk) => {
        data += chunk;
      });
      
      res.on('end', () => {
        try {
          const result = JSON.parse(data);
          resolve(result);
        } catch (error) {
          reject(error);
        }
      });
    }).on('error', reject);
  });
}

// Usage
flipCoin()
  .then(result => {
    console.log(`You got: ${result.result}`);
    console.log(`Session: ${result.session_id}`);
  })
  .catch(error => {
    console.error('Flip failed:', error.message);
  });

Python Example

import requests
import json

def flip_coin():
    """Single coin flip"""
    try:
        response = requests.get('https://flipacoinfree.com/api/flip')
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException as e:
        print(f"Error: {e}")
        return None

def bulk_flip(count=100):
    """Bulk flip operation"""
    try:
        response = requests.post(
            'https://flipacoinfree.com/api/batchflip',
            json={'count': count, 'format': 'summary'}
        )
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException as e:
        print(f"Error: {e}")
        return None

# Example usage
if __name__ == '__main__':
    # Single flip
    result = flip_coin()
    if result:
        print(f"Result: {result['result']}")
    
    # Bulk flip
    bulk_result = bulk_flip(1000)
    if bulk_result:
        print(f"Heads: {bulk_result['heads']}")
        print(f"Tails: {bulk_result['tails']}")
        print(f"Distribution: {bulk_result['distribution']}")

PHP Example

<?php
// PHP example with cURL
function flipCoin() {
    $ch = curl_init('https://flipacoinfree.com/api/flip');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    if ($httpCode === 200) {
        return json_decode($response, true);
    }
    
    return null;
}

function bulkFlip($count = 100) {
    $ch = curl_init('https://flipacoinfree.com/api/batchflip');
    
    $data = json_encode([
        'count' => $count,
        'format' => 'summary'
    ]);
    
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Content-Type: application/json',
        'Content-Length: ' . strlen($data)
    ]);
    
    $response = curl_exec($ch);
    curl_close($ch);
    
    return json_decode($response, true);
}

// Usage
$result = flipCoin();
echo "Result: " . $result['result'] . "\n";

$bulkResult = bulkFlip(500);
echo "Heads: " . $bulkResult['heads'] . "\n";
echo "Tails: " . $bulkResult['tails'] . "\n";
?>

Security and Best Practices

After working with thousands of developers, we've compiled the most important security considerations and best practices for production deployments.

1. Always Implement Error Handling

Network requests can fail. Always wrap API calls in try-catch blocks and provide fallback behavior:

async function safeFlip() {
  try {
    const response = await fetch('https://flipacoinfree.com/api/flip');
    
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    
    return await response.json();
  } catch (error) {
    console.error('Flip failed:', error);
    // Fallback: use local randomization
    return { result: Math.random() < 0.5 ? 'heads' : 'tails' };
  }
}

2. Respect Rate Limits

Implement exponential backoff when you hit rate limits:

async function flipWithRetry(maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch('https://flipacoinfree.com/api/flip');
      
      if (response.status === 429) { // Rate limited
        const waitTime = Math.pow(2, i) * 1000; // Exponential backoff
        await new Promise(resolve => setTimeout(resolve, waitTime));
        continue;
      }
      
      return await response.json();
    } catch (error) {
      if (i === maxRetries - 1) throw error;
    }
  }
}

3. Cache Results When Appropriate

For scenarios where multiple users see the same result (like a daily challenge), cache the API response:

// Cache daily flip result
const cache = new Map();

async function getDailyFlip() {
  const today = new Date().toDateString();
  
  if (cache.has(today)) {
    return cache.get(today);
  }
  
  const result = await fetch('https://flipacoinfree.com/api/flip')
    .then(r => r.json());
  
  cache.set(today, result);
  return result;
}

4. Verify Results for High-Stakes Decisions

For giveaways or important decisions, save the session_id and hash for audit purposes:

async function auditableFlip(userId) {
  const result = await fetch('https://flipacoinfree.com/api/flip')
    .then(r => r.json());
  
  // Save to database
  await database.insert('flip_audit', {
    user_id: userId,
    result: result.result,
    session_id: result.session_id,
    hash: result.hash,
    timestamp: result.timestamp
  });
  
  return result;
}

5. Use Batch Operations for Efficiency

Instead of making 1000 individual API calls, use one batch request:

❌ Don't do this: Making sequential API calls in a loop

// BAD: Multiple requests
for (let i = 0; i < 1000; i++) {
  await fetch('https://flipacoinfree.com/api/flip');
}

✅ Do this instead: Use batch endpoint

// GOOD: Single batch request
const results = await fetch('https://flipacoinfree.com/api/batchflip', {
  method: 'POST',
  body: JSON.stringify({ count: 1000 })
}).then(r => r.json());

6. Secure Your API Keys

If you're using an API key, never expose it in frontend JavaScript. Always make API calls from your backend:

// Backend server (Node.js/Express example)
app.get('/flip', async (req, res) => {
  const result = await fetch('https://flipacoinfree.com/api/flip', {
    headers: {
      'X-API-Key': process.env.FLIPACOIN_API_KEY // From environment variable
    }
  }).then(r => r.json());
  
  res.json(result);
});

// Frontend calls your backend
fetch('/flip').then(r => r.json());

Common Issues and Solutions

Issue: CORS Error in Browser

Problem: Getting "CORS policy" error when calling API from frontend JavaScript.

Solution: Our API supports CORS for public endpoints. Make sure you're using the correct URL and not blocking third-party requests. If the issue persists, call the API from your backend instead.

Issue: 429 Rate Limit Error

Problem: Getting HTTP 429 "Too Many Requests" response.

Solution: You've exceeded the rate limit. Implement exponential backoff (see best practices above) or upgrade to an API key for higher limits. Check the X-RateLimit-Reset header to see when you can retry.

Issue: Slow Response Times

Problem: API calls taking longer than expected.

Solution: Our API typically responds in under 100ms globally. Slow responses usually indicate network issues on your end. Try adding a timeout to your requests and implement retry logic. For bulk operations, use the batch endpoint instead of sequential calls.

Issue: Widget Not Displaying

Problem: iframe embed shows blank or doesn't load.

Solution: Check that your Content Security Policy (CSP) allows iframes from flipacoinfree.com. Add this to your HTML header if needed:

<meta http-equiv="Content-Security-Policy" 
      content="frame-src https://flipacoinfree.com">

Issue: Results Seem Non-Random

Problem: Getting too many heads or tails in a row.

Solution: This is actually expected behavior with true randomness. Humans expect patterns, but real randomness produces streaks. Our system uses cryptographically secure random number generation and has been independently tested. Over millions of flips, the distribution is 50.02% heads, 49.98% tails—statistically perfect. Short-term streaks are normal and prove authenticity.

Frequently Asked Questions

How do I embed the coin flip widget on my website?

You can embed the coin flip widget using our iframe snippet or JavaScript SDK. The iframe method takes 2 minutes to set up and requires no coding knowledge. Simply copy the embed code from our widget page and paste it into your HTML. For advanced customization, use our JavaScript SDK which allows theme customization, event callbacks, and programmatic control.

Does FlipACoinFree provide an API for developers?

Yes, we provide a REST API with endpoints for single flips (/api/flip) and batch operations (/api/batchflip). The API returns JSON responses and supports up to 1000 flips per request. Visit our API documentation for authentication details, rate limits, and code examples in JavaScript, Python, and PHP.

Can I run bulk flips for giveaways and export results?

Absolutely. Our bulk flip feature supports running up to 10,000 flips at once, perfect for large giveaways, raffles, and statistical analysis. Results can be exported as CSV or JSON with timestamps, making them ideal for audits and record-keeping. Each bulk operation includes a unique session ID for tracking.

Is the embed widget free to use on commercial websites?

Yes, the embed widget is completely free for both personal and commercial use. There are no hidden fees, licensing costs, or attribution requirements. We only ask that you don't remove or modify our branding within the widget itself. Premium API features with higher rate limits are available for enterprise users.

How do I ensure flip results are fair and auditable?

Our system uses cryptographically secure random number generation (CSPRNG) for all flips. Every flip includes a verifiable hash that can be independently validated. For transparency, we log timestamps and session IDs. Bulk flip results include statistical distribution data so you can verify randomness. Our algorithm has been independently tested and shows a 50.02% heads rate over 10 million flips—statistically perfect randomness.

What's the difference between iframe embed and JavaScript SDK?

The iframe embed is simpler—just copy and paste HTML. It works immediately but offers limited customization. The JavaScript SDK requires slightly more setup but gives you full programmatic control, event callbacks, and the ability to integrate with your application state. Use iframe for blogs and simple sites; use SDK for web apps and custom user experiences.

Can I use this for legal binding decisions or gambling?

Our tool is designed for entertainment, education, and non-binding decision-making. While we use cryptographically secure randomization, we do not provide any legal guarantees or certifications for gambling, financial decisions, or legally binding agreements. For regulated gaming or legal purposes, consult with appropriate authorities and use certified random number generators.

Do you log or store flip results?

We log aggregate statistics (total flips, global distribution) for performance monitoring but do not store individual flip results or associate them with user identities. Session IDs are generated for each request but contain no personal information. For complete privacy details, see our privacy policy.

What happens if the API is down?

We maintain 99.9% uptime with global CDN distribution. In the rare case of downtime, implement a fallback in your code using Math.random() for local randomization. Our status page at status.flipacoinfree.com shows real-time availability. For enterprise users, we offer SLA guarantees and dedicated support.

Additional Developer Resources

Need Help or Have Questions?

Our developer community is here to help. Join our Discord server, check our GitHub discussions, or contact our technical support team. We typically respond within 24 hours.