# API AI Prompt Setup Source: https://docs.getsnippets.ai/api-reference/api-ai-prompt-setup Set up Snippets AI API access in seconds using AI-powered assistance ## Set up Snippets AI API access in seconds Copy the AI instruction prompt and paste it into your IDE AI agent (Cursor, Windsurf, GitHub Copilot, etc.) so it can set up API access quickly. Click to get the AI setup prompt that will configure your API access automatically ## How It Works The AI setup prompt contains pre-configured instructions that guide your IDE's AI agent through the entire API setup process. Simply copy the prompt and let AI handle the technical details. ### Quick Steps Click the button above to access the AI setup prompt Copy the entire prompt from the page Paste it into your IDE's AI chat or prompt box Your AI agent will automatically configure the Snippets AI API access for you ## Supported AI Agents This setup prompt works with any IDE that has an AI agent with a prompt box: Cursor AI IDE Windsurf AI IDE GitHub Copilot Chat VS Code with AI extensions JetBrains AI Assistant Zed AI Claude for coding Cline AI Assistant Aider AI coding assistant ## What Gets Set Up The AI prompt will help you: * πŸ”‘ Configure your API authentication * πŸ“ Set up proper headers and base URLs * βš™οΈ Create reusable API client functions * πŸ§ͺ Add example requests to test the connection * πŸ“š Include error handling best practices ## Benefits Skip the manual setup process. Let AI configure everything in seconds instead of spending 15-20 minutes reading documentation and writing boilerplate code. The AI ensures proper authentication, correct headers, and follows best practices automatically - no typos or configuration mistakes. Start making API calls right away. The AI sets up working examples you can run immediately to verify your connection. The generated code includes comments and follows industry best practices for API integration, helping you learn as you go. ## Manual Setup Alternative If you prefer to set up the API manually, check out our comprehensive guides: Complete API overview and quick start guide Step-by-step authentication setup ## Need Help? Get help from our team Full API reference # Authentication Source: https://docs.getsnippets.ai/api-reference/authentication Learn how to authenticate your API requests ## Overview The Snippets AI API uses **Bearer token authentication**. All API requests must include a valid API key in the `Authorization` header. ## Getting Your API Key Navigate to your Snippets AI app Click on **API Access** Click **New API Key** and configure: - **Key name**: A descriptive name for identification - **Team permissions**: Select which teams this key can access - **All teams**: Toggle if you want workspace-wide access Copy the secret key immediately - you won't be able to see it again! **Keep your API key secure!** Never share it publicly or commit it to version control. Anyone with your API key can access your snippets and consume your API quota. ## Using Your API Key Include your API key in the `Authorization` header of every request using the Bearer authentication scheme: ``` Authorization: Bearer YOUR_API_KEY ``` ### Code Examples ```javascript JavaScript theme={null} const axios = require('axios'); const API_KEY = process.env.SNIPPETS_AI_API_KEY; const BASE_URL = 'https://www.getsnippets.ai/api/prompts'; // Configure axios with default headers const api = axios.create({ baseURL: BASE_URL, headers: { Authorization: `Bearer ${API_KEY}`, 'Content-Type': 'application/json', }, }); // Make a request async function getSnippet(id) { const response = await api.get('/snippet', { params: { id }, }); return response.data; } ``` ```python Python theme={null} import os import requests API_KEY = os.environ.get('SNIPPETS_AI_API_KEY') BASE_URL = 'https://www.getsnippets.ai/api/prompts' # Create a session with default headers session = requests.Session() session.headers.update({ 'Authorization': f'Bearer {API_KEY}', 'Content-Type': 'application/json' }) # Make a request def get_snippet(snippet_id): response = session.get( f'{BASE_URL}/snippet', params={'id': snippet_id} ) return response.json() ``` ```bash cURL theme={null} # Store your API key in an environment variable export SNIPPETS_AI_API_KEY="your_api_key_here" # Make a request curl -X GET "https://www.getsnippets.ai/api/prompts/snippet?id=snippet_id" \ -H "Authorization: Bearer $SNIPPETS_AI_API_KEY" \ -H "Content-Type: application/json" ``` ```php PHP theme={null} ``` ## Team Permissions API keys can be configured with different levels of access: ### All Teams Access When enabled, the API key has access to all teams in your workspace, including newly created teams. ```json theme={null} { "is_all_teams": true, "team_permissions": [] } ``` ### Specific Team Access Limit the API key to specific teams for better security: ```json theme={null} { "is_all_teams": false, "team_permissions": ["team_uuid_1", "team_uuid_2"] } ``` If you try to access a resource (snippet, folder, or tag) from a team that your API key doesn't have permission for, you'll receive a `403 Forbidden` error. ## Security Best Practices Never hardcode API keys in your source code. Use environment variables or secure secret management systems: ```bash theme={null} # .env file SNIPPETS_AI_API_KEY=your_api_key_here ``` {' '} Periodically rotate your API keys, especially if: - A team member with access leaves - You suspect a key may have been compromised - You're decommissioning an integration {' '} Create API keys with access only to the teams they need. Don't use all-teams access unless necessary. {' '} Regularly check your API usage in the dashboard to detect any unusual activity or unauthorized access. Always make API requests over HTTPS. The API will reject requests made over plain HTTP. ## Managing API Keys ### Viewing API Keys You can view all your API keys in the dashboard, including: * Key name and creation date * Last used timestamp * Team permissions * Active/inactive status ### Deactivating Keys To deactivate an API key: 1. Go to Settings β†’ API Keys 2. Find the key you want to deactivate 3. Click **Deactivate** Deactivated keys will immediately stop working. Any integrations using that key will start receiving `401 Unauthorized` errors. ### Deleting Keys To permanently delete an API key: 1. First deactivate the key 2. Wait at least 24 hours (recommended) 3. Click **Delete** to permanently remove it ## Authentication Errors Common authentication errors and how to resolve them: **Invalid or inactive API key** Your API key is either invalid, has been deactivated, or was never created. ```json theme={null} { "success": false, "message": "Invalid or inactive API key" } ``` **Solution**: Verify your API key is correct and active in the dashboard. **Missing Authorization header** The request didn't include an Authorization header. ```json theme={null} { "success": false, "message": "Authorization header with Bearer token is required" } ``` **Solution**: Ensure you're including `Authorization: Bearer YOUR_API_KEY` in all requests. **Insufficient permissions** Your API key doesn't have access to the requested team. ```json theme={null} { "success": false, "message": "API key does not have access to this team" } ``` **Solution**: Update your API key's team permissions or use a different key. **Inactive subscription** Your workspace subscription is not active. ```json theme={null} { "success": false, "message": "Workspace subscription is not active" } ``` **Solution**: Check your subscription status and update your billing information. ## Testing Your Authentication Use this simple request to verify your API key is working: ```bash theme={null} curl -X GET "https://www.getsnippets.ai/api/prompts/snippet?id=test" \ -H "Authorization: Bearer YOUR_API_KEY" ``` If authentication is successful but the snippet doesn't exist, you'll receive a `404 Not Found` error (which confirms authentication worked). If authentication fails, you'll receive a `401 Unauthorized` error. ## Need Help? If you're having trouble with authentication: Get help from our team # Error Codes Source: https://docs.getsnippets.ai/api-reference/errors Complete reference for API error codes and how to handle them ## Error Response Format All errors follow a consistent JSON format: ```json theme={null} { "success": false, "message": "Human-readable error description", "error": "Additional error details (optional)" } ``` Some errors include additional context in the response: ```json theme={null} { "success": false, "message": "Insufficient API requests", "usage": { "remainingRequests": 0, "requiredRequests": 5 } } ``` ## HTTP Status Codes ### 2xx Success The request was successful. Response includes the requested data. ```json theme={null} { "success": true, "data": { /* requested data */ }, "usage": { "remainingRequests": 99950 } } ``` ### 4xx Client Errors **The request was malformed or contains invalid parameters.** Common causes: * Missing required parameters * Invalid JSON in request body * Invalid parameter values * Invalid data types * Field length violations ```json theme={null} { "success": false, "message": "Snippet ID is required" } ``` **How to fix:** * Check that all required parameters are included * Validate JSON syntax * Verify parameter values match the expected format * Review field length requirements in the API docs **Authentication failed or API key is invalid.** Common causes: * Missing Authorization header * Invalid API key format * Inactive or deleted API key * Expired API key ```json theme={null} { "success": false, "message": "Invalid or inactive API key" } ``` **How to fix:** * Verify the Authorization header is included: `Authorization: Bearer YOUR_KEY` * Check that the API key is correct * Confirm the API key is active in your dashboard * Create a new API key if necessary **The API key doesn't have permission to access the resource.** Common causes: * API key lacks team permissions * Workspace subscription is inactive * Insufficient API request quota * Attempting to access another workspace's resources ```json theme={null} { "success": false, "message": "API key does not have access to this team" } ``` **Insufficient quota example:** ```json theme={null} { "success": false, "message": "Insufficient API requests. This operation requires 5 requests but you have 0 remaining.", "usage": { "remainingRequests": 0, "requiredRequests": 5 } } ``` **How to fix:** * Update API key permissions to include the required teams * Check your workspace subscription status * Purchase additional API requests if quota is exhausted * Verify you're accessing resources in your workspace **The requested resource doesn't exist.** Common causes: * Invalid resource ID * Resource was deleted * Typo in the endpoint URL * Resource belongs to a different workspace ```json theme={null} { "success": false, "message": "Snippet not found" } ``` **How to fix:** * Verify the resource ID is correct * Check if the resource was deleted * Confirm the endpoint URL is correct * Ensure the resource exists in your workspace **Rate limit exceeded (20 requests per minute).** The response includes a `Retry-After` header indicating how long to wait before retrying. ```json theme={null} { "success": false, "message": "Rate limit exceeded. Too many requests from this API key. Try again in 120 seconds." } ``` **Response headers:** ``` Retry-After: 120 ``` **How to fix:** * Implement exponential backoff * Respect the `Retry-After` header * Use request queuing * Leverage batch endpoints to reduce request count * See [Rate Limiting](/api-reference/rate-limiting) for detailed strategies ### 5xx Server Errors **An unexpected error occurred on the server.** ```json theme={null} { "success": false, "message": "Internal server error", "error": "Failed to process request" } ``` **How to fix:** * Retry the request after a short delay * Contact support if the problem continues ## Common Error Scenarios ### Authentication Errors ```json Missing Authorization Header theme={null} { "success": false, "message": "Authorization header with Bearer token is required" } ``` ```json Invalid API Key Format theme={null} { "success": false, "message": "API key cannot be empty" } ``` ```json Inactive API Key theme={null} { "success": false, "message": "Invalid or inactive API key" } ``` ### Validation Errors ```json Missing Required Field theme={null} { "success": false, "message": "Title is required" } ``` ```json Field Length Violation theme={null} { "success": false, "message": "Title cannot exceed 200 characters" } ``` ```json Invalid Data Type theme={null} { "success": false, "message": "Content must be a valid object" } ``` ```json Invalid JSON theme={null} { "success": false, "message": "Invalid JSON in request body" } ``` ### Permission Errors ```json No Team Access theme={null} { "success": false, "message": "API key does not have access to this team" } ``` ```json Wrong Workspace theme={null} { "success": false, "message": "API key does not have access to this workspace" } ``` ```json Inactive Subscription theme={null} { "success": false, "message": "Workspace subscription is not active" } ``` ### Resource Errors ```json Resource Not Found theme={null} { "success": false, "message": "Snippet not found" } ``` ```json Folder Not Found theme={null} { "success": false, "message": "Folder not found or does not belong to the specified workspace/team" } ``` ```json Tag Not Found theme={null} { "success": false, "message": "Tags not found: tag_uuid_1, tag_uuid_2" } ``` ### Quota Errors ```json Insufficient Requests theme={null} { "success": false, "message": "Insufficient API requests. This operation requires 10 requests but you only have 5 remaining.", "usage": { "remainingRequests": 5, "requiredRequests": 10 } } ``` ```json No Requests Remaining theme={null} { "success": false, "message": "No API requests remaining", "usage": { "remainingRequests": 0 } } ``` ### Variation Errors ```json Cannot Delete Last Variation theme={null} { "success": false, "message": "Cannot delete variations. The following snippets would have no variations left: My Snippet. Snippets must have at least one variation.", "affectedSnippets": [ { "snippetId": "snippet_uuid", "title": "My Snippet" } ] } ``` ```json Variation Not Found theme={null} { "success": false, "message": "Variations not found: variation_uuid_1, variation_uuid_2" } ``` ### Batch Operation Errors ```json Partial Success theme={null} { "success": true, "data": { "message": "Some snippets created successfully", "createdSnippets": [ /* ... */ ] }, "usage": { "remainingRequests": 99900, "usageDeducted": 100 }, "metadata": { "requestedCount": 100, "createdCount": 95, "failedCount": 5, "isPartialSuccess": true, "failures": [ { "originalIndex": 10, "title": "Failed Snippet", "error": "Folder not found" } ] } } ``` ```json Complete Failure theme={null} { "success": false, "message": "Failed to create any snippets", "usage": { "remainingRequests": 99900, "usageDeducted": 100 }, "failures": [ /* ... */ ] } ``` ## Error Handling Best Practices ### Retry Strategy Implement intelligent retry logic with exponential backoff: ```javascript theme={null} async function apiCallWithRetry(apiCall, maxRetries = 3) { for (let attempt = 0; attempt < maxRetries; attempt++) { try { return await apiCall(); } catch (error) { const status = error.response?.status; // Don't retry client errors (except 429) if (status >= 400 && status < 500 && status !== 429) { throw error; } // For 429 or 5xx, wait and retry if (attempt < maxRetries - 1) { const baseDelay = status === 429 ? parseInt(error.response?.headers['retry-after'] || 60) * 1000 : 1000; const delay = baseDelay * Math.pow(2, attempt); await new Promise((resolve) => setTimeout(resolve, delay)); } else { throw error; } } } } ``` ### Comprehensive Error Handler ```javascript theme={null} function handleAPIError(error) { if (!error.response) { // Network error console.error('Network error:', error.message); return { type: 'network', message: 'Unable to connect to the API', retryable: true, }; } const { status, data } = error.response; switch (status) { case 400: return { type: 'validation', message: data.message || 'Invalid request', retryable: false, }; case 401: return { type: 'authentication', message: 'Invalid API key', retryable: false, action: 'CHECK_API_KEY', }; case 403: if (data.message?.includes('API requests')) { return { type: 'quota', message: 'API quota exceeded', retryable: false, action: 'UPGRADE_PLAN', }; } return { type: 'permission', message: data.message || 'Insufficient permissions', retryable: false, action: 'UPDATE_PERMISSIONS', }; case 404: return { type: 'not_found', message: data.message || 'Resource not found', retryable: false, }; case 429: return { type: 'rate_limit', message: 'Rate limit exceeded', retryable: true, retryAfter: error.response.headers['retry-after'], }; case 500: default: return { type: 'server', message: 'Server error occurred', retryable: true, }; } } // Usage try { const result = await apiCall(); } catch (error) { const errorInfo = handleAPIError(error); if (errorInfo.retryable) { // Retry logic } else { // Show user-friendly error message console.error(errorInfo.message); } } ``` ### User-Friendly Messages Map technical errors to user-friendly messages: ```javascript theme={null} const ERROR_MESSAGES = { 'Invalid or inactive API key': 'There was an authentication problem. Please contact support.', 'API key does not have access to this team': "You don't have permission to access this resource.", 'Insufficient API requests': 'API usage limit reached. Please upgrade your plan.', 'Rate limit exceeded': 'Too many requests. Please wait a moment and try again.', 'Snippet not found': "The snippet you're looking for doesn't exist or was deleted.", default: 'Something went wrong. Please try again or contact support.', }; function getUserFriendlyMessage(apiError) { return ERROR_MESSAGES[apiError.message] || ERROR_MESSAGES.default; } ``` ## Logging and Monitoring Track errors to identify patterns and issues: ```javascript theme={null} class APILogger { logError(error, context) { const logEntry = { timestamp: new Date().toISOString(), status: error.response?.status, message: error.response?.data?.message, endpoint: context.endpoint, method: context.method, requestId: error.response?.headers['x-request-id'], // Don't log API keys! user: context.userId, }; // Send to your logging service console.error('API Error:', logEntry); // Alert on critical errors if (error.response?.status >= 500) { this.alertTeam(logEntry); } } alertTeam(logEntry) { // Send to Slack, PagerDuty, etc. } } ``` ## Need Help? If you're experiencing persistent errors: Contact our support team Review the full API documentation # Create Folder Source: https://docs.getsnippets.ai/api-reference/folders/create-folder POST /folder Creates a new folder. API Cost: 1 request. # Create Multiple Folders Source: https://docs.getsnippets.ai/api-reference/folders/create-folders POST /folders Creates multiple folders in a single request. API Cost: N requests (one per folder). # Delete Folder Source: https://docs.getsnippets.ai/api-reference/folders/delete-folder DELETE /folder Deletes a folder. Contained snippets are orphaned (folder_id set to null). API Cost: 1 request. # Delete Multiple Folders Source: https://docs.getsnippets.ai/api-reference/folders/delete-folders DELETE /folders Deletes multiple folders by their IDs. API Cost: N requests (one per folder). # Get Folder Source: https://docs.getsnippets.ai/api-reference/folders/get-folder GET /folder Retrieves a folder's metadata and its snippets with pagination. API Cost: 1 + N requests (1 for folder + N for snippets). # Get Multiple Folders Source: https://docs.getsnippets.ai/api-reference/folders/get-folders GET /folders Retrieves multiple folders and their snippets. API Cost: M + N requests (M for folders + N for total snippets). # Update Folder Source: https://docs.getsnippets.ai/api-reference/folders/update-folder PUT /folder Updates an existing folder. API Cost: 1 request. # Update Multiple Folders Source: https://docs.getsnippets.ai/api-reference/folders/update-folders PUT /folders Updates multiple folders in a single request. API Cost: N requests (one per folder). # Introduction Source: https://docs.getsnippets.ai/api-reference/introduction Getting started with the Snippets AI API ## Welcome to the Snippets AI API The Snippets AI API allows you to programmatically manage snippets, folders, tags, and variations. Build powerful integrations to automate your workflow and sync your code snippets across different platforms. Learn how to authenticate your API requests Understand rate limits and usage quotas Reference for all API error codes Learn about API usage costs and billing ## Base URL All API requests should be made to: ``` https://www.getsnippets.ai/api/prompts ``` ## Quick Start Get up and running in minutes: ### 1. Get Your API Key 1. Log into your Snippets AI workspace 2. Navigate to Admin β†’ API Access 3. Create a new API key with appropriate team permissions 4. Copy the secret key (you won't be able to see it again) ### 2. Make Your First Request Here's a simple example to fetch a snippet: ```javascript theme={null} const axios = require('axios'); const API_KEY = 'your_api_key_here'; const BASE_URL = 'https://www.getsnippets.ai/api/prompts'; async function getSnippet(snippetId) { try { const response = await axios.get(`${BASE_URL}/snippet`, { headers: { Authorization: `Bearer ${API_KEY}`, }, params: { id: snippetId, }, }); console.log('Snippet:', response.data); return response.data; } catch (error) { console.error('Error:', error.response?.data || error.message); } } getSnippet('your-snippet-id'); ``` ```python theme={null} import requests API_KEY = 'your_api_key_here' BASE_URL = 'https://www.getsnippets.ai/api/prompts' def get_snippet(snippet_id): headers = { 'Authorization': f'Bearer {API_KEY}' } params = { 'id': snippet_id } response = requests.get( f'{BASE_URL}/snippet', headers=headers, params=params ) if response.status_code == 200: print('Snippet:', response.json()) return response.json() else: print('Error:', response.json()) get_snippet('your-snippet-id') ``` ```bash theme={null} curl -X GET "https://www.getsnippets.ai/api/prompts/snippet?id=your-snippet-id" \ -H "Authorization: Bearer your_api_key_here" ``` ## API Resources The API is organized around four main resource types: Manage your code and text snippets Handle multiple versions of snippets Organize snippets into folders Categorize snippets with tags ## Key Features ### πŸ” Secure Authentication All requests use Bearer token authentication with API keys that have granular team-level permissions. ### ⚑ Rate Limited The API is rate-limited to 20 requests per minute per API key to ensure fair usage and system stability. ### πŸ’° Usage-Based Billing Pay only for what you use: \$10 per 100,000 API requests. Each endpoint clearly documents its cost. ### πŸ“Š Detailed Metadata Every response includes usage information, pagination details, and comprehensive metadata about the operation. ### πŸ”„ Batch Operations Save on API costs by using batch endpoints to create, update, or delete multiple resources at once. ## Response Format All API responses follow a consistent format: ```json theme={null} { "success": true, "data": { // Response data here }, "usage": { "remainingRequests": 99850 }, "metadata": { // Additional metadata } } ``` ### Success Response * `success`: Boolean indicating if the request was successful * `data`: The requested data or result * `usage`: Information about API usage and remaining quota * `metadata`: Additional context about the operation ### Error Response * `success`: Always `false` for errors * `message`: Human-readable error description * `error`: Additional error details (when available) ## Need Help? Full documentation and guides Contact our support team # Rate Limiting Source: https://docs.getsnippets.ai/api-reference/rate-limiting Understand API rate limits and how to handle them ## Overview To ensure fair usage and maintain system performance, the Snippets AI API implements rate limiting specifically for invalid API key attempts. **20 invalid attempts** within a rolling window will result in a **5-minute block** for that API key. ### General Rate Limit There is **no general rate limit** for valid API requests. You can make as many valid requests as needed without encountering rate limiting errors, provided your API key is valid and has the necessary permissions. ## How the Invalid API Key Block Works This security measure helps prevent brute-force attacks on API keys: * Each API key has a counter for invalid access attempts. * If 20 invalid attempts are detected within a short rolling window, the API key will be temporarily blocked. * The block lasts for 5 minutes, after which the key is automatically unblocked, and the counter resets. ### Invalid Attempt Criteria An "invalid attempt" is counted when: * An API request is made with a non-existent API key. * An API request is made with a valid API key, but it lacks the necessary permissions for the requested resource (e.g., wrong team ID). ## Checking Your API Key Status ### Blocked API Key Errors When your API key is temporarily blocked due to excessive invalid attempts, you'll receive a `403 Forbidden` response (or similar, depending on exact implementation): ```json theme={null} { "success": false, "message": "Too many invalid API key attempts. This API key has been temporarily blocked for 5 minutes." } ``` This response may also include a `Retry-After` header with the number of seconds until the block is lifted. ## Handling Invalid API Key Blocks ### Exponential Backoff (Modified) If you encounter a `403 Forbidden` error specifically related to an API key block, you should cease attempts for the specified `Retry-After` duration. If no `Retry-After` is provided, assume a 5-minute (300-second) wait. ```javascript JavaScript theme={null} const axios = require('axios'); async function makeRequestWithBackoff(url, options, maxRetries = 3) { for (let i = 0; i < maxRetries; i++) { try { const response = await axios(url, options); return response.data; } catch (error) { if ( error.response?.status === 403 && error.response?.data?.message?.includes( 'Too many invalid API key attempts' ) ) { // Get retry-after from header (in seconds), default to 300 (5 minutes) const retryAfter = parseInt( error.response.headers['retry-after'] || 300 ); const waitTime = retryAfter * 1000; console.log(`API key blocked. Waiting ${waitTime / 1000} seconds...`); await new Promise((resolve) => setTimeout(resolve, waitTime)); // Retry the request after the block period continue; } // Re-throw other errors, including other 403s (e.g., permission issues) throw error; } } throw new Error('Max retries exceeded for API key block'); } // Usage const result = await makeRequestWithBackoff( 'https://www.getsnippets.ai/api/prompts/snippet', { method: 'GET', headers: { Authorization: `Bearer ${API_KEY}`, }, params: { id: 'snippet_id' }, } ); ``` ```python Python theme={null} import time import requests def make_request_with_backoff( url: str, headers: dict, params: Optional[dict] = None, max_retries: int = 3 ) -> dict: for attempt in range(max_retries): try: response = requests.get(url, headers=headers, params=params) response.raise_for_status() return response.json() except requests.exceptions.HTTPError as e: if e.response.status_code == 403 and "Too many invalid API key attempts" in e.response.json().get("message", ""): # API key blocked - wait and retry retry_after = int( e.response.headers.get('Retry-After', 300) ) print(f"API key blocked. Waiting {retry_after} seconds...") time.sleep(retry_after) # Retry the request continue # Re-raise other errors, including other 403s raise raise Exception('Max retries exceeded for API key block') # Usage result = make_request_with_backoff( 'https://www.getsnippets.ai/api/prompts/snippet', headers={'Authorization': f'Bearer {API_KEY}'}, params={'id': 'snippet_id'} ) ``` ## Best Practices Always ensure you are using a valid and active API key. Double-check your key and its permissions in the Snippets AI dashboard. {' '} Distinguish between different 4xx errors. A `401 Unauthorized` means a generally invalid key, while a `403 Forbidden` *might* indicate a temporary block if the message specifically mentions "Too many invalid API key attempts". {' '} Do not repeatedly try invalid API keys. This will lead to temporary blocks. Regularly monitor logs and error reports from your applications to quickly identify if an API key is being blocked. ## FAQs No, there is no general rate limit for valid API requests. You can make as many valid requests as your account quota allows. {' '} Your API key will be temporarily blocked for 5 minutes after 20 invalid attempts. During this time, all requests with that key will fail. {' '} No, requests made with a temporarily blocked API key do not consume from your API request quota. However, invalid attempts that lead to the block do count towards the 20-attempt limit. Repeated and excessive attempts to bypass the security block may lead to a permanent ban of the API key or even the associated workspace. We recommend resolving the underlying issue rather than repeatedly hitting the block. ## Need Help? If you're having trouble with API key blocks: Get help from our team # Create Snippet Source: https://docs.getsnippets.ai/api-reference/snippets/create-snippet POST /snippet Creates a new snippet with optional variations and tags. API Cost: 1 request. ## Overview Creates a new snippet with optional variations, folder assignment, and tags. This endpoint allows you to create structured snippets programmatically. **API Cost**: 1 request ## Code Examples ```javascript JavaScript - Basic Snippet theme={null} const axios = require('axios'); const API_KEY = process.env.SNIPPETS_AI_API_KEY; const BASE_URL = 'https://www.getsnippets.ai/api/prompts'; async function createSnippet(snippetData) { try { const response = await axios.post(`${BASE_URL}/snippet`, snippetData, { headers: { Authorization: `Bearer ${API_KEY}`, 'Content-Type': 'application/json', }, }); console.log('Created snippet ID:', response.data.data.snippetId); console.log('Remaining requests:', response.data.usage.remainingRequests); return response.data; } catch (error) { console.error('Error:', error.response?.data || error.message); throw error; } } // Basic snippet const basicSnippet = { title: 'My API Snippet', content: { type: 'plaintext', content: "console.log('Hello, World!');", }, teamId: 'your-team-id', }; createSnippet(basicSnippet); ``` ```javascript JavaScript - Full-Featured Snippet theme={null} // Snippet with all optional fields const fullSnippet = { title: 'Customer Onboarding Email', content: { type: 'plaintext', content: 'Dear {{customer_name}},\n\nWelcome to our platform!', }, teamId: 'your-team-id', note: 'Use this template for new customer onboarding', shortcut: 'welcome_email', folderId: 'folder-uuid', tagIds: ['tag-uuid-1', 'tag-uuid-2'], additionalVariations: [ { content: { type: 'plaintext', content: 'Hola {{customer_name}},\n\nΒ‘Bienvenido!', }, variationName: 'Spanish Version', }, { content: { type: 'plaintext', content: 'Bonjour {{customer_name}},\n\nBienvenue!', }, variationName: 'French Version', }, ], }; createSnippet(fullSnippet); ``` ```python Python theme={null} import os import requests API_KEY = os.environ.get('SNIPPETS_AI_API_KEY') BASE_URL = 'https://www.getsnippets.ai/api/prompts' def create_snippet(snippet_data): try: response = requests.post( f'{BASE_URL}/snippet', headers={ 'Authorization': f'Bearer {API_KEY}', 'Content-Type': 'application/json' }, json=snippet_data ) response.raise_for_status() data = response.json() print(f"Created snippet ID: {data['data']['snippetId']}") print(f"Remaining requests: {data['usage']['remainingRequests']}") return data except requests.exceptions.HTTPError as e: print(f"Error: {e.response.json().get('message')}") raise # Basic snippet basic_snippet = { 'title': 'My API Snippet', 'content': { 'type': 'plaintext', 'content': 'print("Hello, World!")' }, 'teamId': 'your-team-id' } create_snippet(basic_snippet) ``` ```bash cURL theme={null} curl -X POST "https://www.getsnippets.ai/api/prompts/snippet" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "title": "My API Snippet", "content": { "type": "plaintext", "content": "Hello, World!" }, "teamId": "your-team-id", "note": "Created via API", "folderId": "folder-uuid", "tagIds": ["tag-uuid-1"] }' ``` ## Real-World Use Case: Voice AI Integration Here's a complete example of creating prompts for a voice AI system (like VAPI): ```javascript theme={null} async function createVoiceAgentPrompts(clientData) { const { clientName, industry, teamId, folderId } = clientData; // Create a snippet with multiple language variations const snippet = { title: `${clientName} - ${industry} Agent`, content: { type: 'plaintext', content: `You are a professional ${industry} assistant for ${clientName}. Your role is to help customers with inquiries, schedule appointments, and provide information about services. Be polite, professional, and helpful.`, }, teamId: teamId, folderId: folderId, note: `Voice agent prompt for ${clientName}`, shortcut: `${clientName.toLowerCase()}_agent`, tagIds: [industryTagId, voiceAgentTagId], additionalVariations: [ { content: { type: 'plaintext', content: `Eres un asistente profesional de ${industry} para ${clientName}. Tu funciΓ³n es ayudar a los clientes con consultas, programar citas y proporcionar informaciΓ³n sobre servicios. SΓ© cortΓ©s, profesional y servicial.`, }, variationName: 'Spanish Version', }, { content: { type: 'plaintext', content: `You are handling after-hours calls for ${clientName}. Inform customers of business hours and offer to schedule a callback during office hours. Be understanding and helpful.`, }, variationName: 'After Hours', }, ], }; try { const response = await createSnippet(snippet); console.log(`βœ… Created voice agent prompt: ${response.data.snippetId}`); console.log(` Variations: ${response.data.metadata.totalVariations}`); return response.data.snippetId; } catch (error) { console.error( `❌ Failed to create prompt for ${clientName}:`, error.message ); throw error; } } // Usage createVoiceAgentPrompts({ clientName: 'Dental Clinic ABC', industry: 'Healthcare', teamId: 'healthcare-team-id', folderId: 'dental-clients-folder-id', }); ``` ## Response Example ```json theme={null} { "success": true, "data": { "snippetId": "550e8400-e29b-41d4-a716-446655440000" }, "usage": { "remainingRequests": 99999 }, "metadata": { "totalVariations": 3, "tagsAttached": 2 } } ``` ## Validation Rules **Length**: 1-200 characters Cannot be empty or exceed 200 characters. Must include `type` and `content` fields. ```json theme={null} { "type": "plaintext", "content": "Your content here" } ``` Must be a valid team ID that your API key has access to. **Length**: 0-5000 characters (optional) **Length**: 0-100 characters (optional) Must be a valid folder ID in the same team (optional) Array of valid tag IDs from the same team (optional) ## Batch Creation To create multiple snippets, use the [batch endpoint](/api-reference/snippets/create-snippets) instead: ```javascript theme={null} // Instead of this (inefficient): for (const snippetData of snippets) { await createSnippet(snippetData); // N API calls + N * rate limit issues } // Do this (efficient): await createSnippets({ snippets }); // 1 API call, N request cost ``` ## Error Handling ```javascript Validation Error Handling theme={null} async function createSnippetSafe(snippetData) { // Pre-validate before API call if (!snippetData.title || snippetData.title.length === 0) { throw new Error('Title is required'); } if (snippetData.title.length > 200) { throw new Error('Title cannot exceed 200 characters'); } if (!snippetData.content) { throw new Error('Content is required'); } if (!snippetData.teamId) { throw new Error('Team ID is required'); } if (snippetData.note && snippetData.note.length > 5000) { throw new Error('Note cannot exceed 5000 characters'); } try { return await createSnippet(snippetData); } catch (error) { const status = error.response?.status; const message = error.response?.data?.message; if (status === 400) { throw new Error(`Validation error: ${message}`); } else if (status === 403) { if (message?.includes('team')) { throw new Error('API key does not have access to this team'); } else if (message?.includes('folder')) { throw new Error('Folder not found or not accessible'); } else if (message?.includes('tag')) { throw new Error('One or more tags not found'); } } throw error; } } ``` ## Best Practices **Validate data before API calls** to catch errors early and save on API costs **Use meaningful titles** that make snippets easy to identify **Add notes** to provide context for team members **Organize with folders** and tags for better management **Create variations** for different use cases (languages, contexts, etc.) Always verify that folder IDs and tag IDs exist and belong to the correct team before creating snippets. ## Related Endpoints * [Update Snippet](/api-reference/snippets/update-snippet) - Update an existing snippet * [Create Multiple Snippets](/api-reference/snippets/create-snippets) - Batch create snippets * [Get Snippet](/api-reference/snippets/get-snippet) - Retrieve a snippet * [Create Folder](/api-reference/folders/create-folder) - Create a folder first # Create Multiple Snippets Source: https://docs.getsnippets.ai/api-reference/snippets/create-snippets POST /snippets Creates multiple snippets in a single request. API Cost: N requests (one per snippet). # Delete Snippet Source: https://docs.getsnippets.ai/api-reference/snippets/delete-snippet DELETE /snippet Deletes a snippet by its ID. API Cost: 1 request. # Delete Multiple Snippets Source: https://docs.getsnippets.ai/api-reference/snippets/delete-snippets DELETE /snippets Deletes multiple snippets by their IDs. API Cost: N requests (one per accessible snippet). # Get Snippet Source: https://docs.getsnippets.ai/api-reference/snippets/get-snippet GET /snippet Retrieves a single snippet by its ID. API Cost: 1 request. ## Overview Retrieves a single snippet by its ID. This endpoint returns the complete snippet data including content, metadata, folder assignment, and timestamps. **API Cost**: 1 request ## Code Examples ```javascript JavaScript theme={null} const axios = require('axios'); const API_KEY = process.env.SNIPPETS_AI_API_KEY; const BASE_URL = 'https://www.getsnippets.ai/api/prompts'; async function getSnippet(snippetId) { try { const response = await axios.get(`${BASE_URL}/snippet`, { headers: { Authorization: `Bearer ${API_KEY}`, }, params: { id: snippetId, }, }); console.log('Snippet:', response.data.data); console.log('Remaining requests:', response.data.usage.remainingRequests); return response.data; } catch (error) { if (error.response) { console.error('Error:', error.response.data.message); console.error('Status:', error.response.status); } else { console.error('Error:', error.message); } throw error; } } // Usage getSnippet('550e8400-e29b-41d4-a716-446655440000'); ``` ```python Python theme={null} import os import requests API_KEY = os.environ.get('SNIPPETS_AI_API_KEY') BASE_URL = 'https://www.getsnippets.ai/api/prompts' def get_snippet(snippet_id): try: response = requests.get( f'{BASE_URL}/snippet', headers={'Authorization': f'Bearer {API_KEY}'}, params={'id': snippet_id} ) response.raise_for_status() data = response.json() print('Snippet:', data['data']) print('Remaining requests:', data['usage']['remainingRequests']) return data except requests.exceptions.HTTPError as e: print(f'Error: {e.response.json().get("message")}') print(f'Status: {e.response.status_code}') raise # Usage get_snippet('550e8400-e29b-41d4-a716-446655440000') ``` ```bash cURL theme={null} curl -X GET "https://www.getsnippets.ai/api/prompts/snippet?id=550e8400-e29b-41d4-a716-446655440000" \ -H "Authorization: Bearer YOUR_API_KEY" ``` ```php PHP theme={null} ``` ## Response Example ```json theme={null} { "success": true, "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "title": "Welcome Email Template", "content": { "type": "plaintext", "content": "Welcome to our platform! We're excited to have you." }, "snippet_note": "Use for new user onboarding", "shortcut": "welcome_email", "folder_id": "660e8400-e29b-41d4-a716-446655440001", "team_id": "770e8400-e29b-41d4-a716-446655440002", "workspace_id": "880e8400-e29b-41d4-a716-446655440003", "is_archived": false, "created_at": "2024-01-15T10:30:00Z", "updated_at": "2024-01-20T14:45:00Z", "created_by": "990e8400-e29b-41d4-a716-446655440004" }, "usage": { "remainingRequests": 99999 } } ``` ## Use Cases Retrieve a specific prompt variation for use in voice AI services like VAPI: ```javascript theme={null} async function getPromptForVoiceAgent(snippetId) { const response = await getSnippet(snippetId); const promptContent = response.data.content.content; // Use with VAPI or similar service const vapiCall = await initiateVoiceCall({ systemPrompt: promptContent, phoneNumber: customerPhone }); return vapiCall; } ``` Fetch snippet data to display in your application: ```javascript theme={null} async function displaySnippet(snippetId) { const response = await getSnippet(snippetId); const snippet = response.data; // Render in UI document.getElementById('snippet-title').textContent = snippet.title; document.getElementById('snippet-content').textContent = snippet.content.content; document.getElementById('snippet-note').textContent = snippet.snippet_note || 'No notes'; } ``` Check if a snippet exists before performing operations: ```javascript theme={null} async function safeUpdateSnippet(snippetId, updates) { try { // Verify snippet exists await getSnippet(snippetId); // Proceed with update return await updateSnippet(snippetId, updates); } catch (error) { if (error.response?.status === 404) { console.log('Snippet not found, creating new one'); return await createSnippet(updates); } throw error; } } ``` Implement caching to reduce API calls: ```javascript theme={null} const cache = new Map(); const CACHE_TTL = 5 * 60 * 1000; // 5 minutes async function getCachedSnippet(snippetId) { const cached = cache.get(snippetId); if (cached && Date.now() - cached.timestamp < CACHE_TTL) { console.log('Cache hit - saved 1 API request'); return cached.data; } const response = await getSnippet(snippetId); cache.set(snippetId, { data: response.data, timestamp: Date.now() }); return response.data; } ``` ## Error Handling ```javascript Comprehensive Error Handling theme={null} async function getSnippetSafely(snippetId) { try { return await getSnippet(snippetId); } catch (error) { const status = error.response?.status; const message = error.response?.data?.message; switch (status) { case 400: throw new Error(`Invalid request: ${message}`); case 401: throw new Error('Invalid API key - check your authentication'); case 403: throw new Error('Access denied - check team permissions'); case 404: throw new Error(`Snippet ${snippetId} not found`); case 429: const retryAfter = error.response.headers['retry-after']; throw new Error(`Rate limit exceeded. Retry after ${retryAfter}s`); default: throw new Error(`API error: ${message || 'Unknown error'}`); } } } ``` ```python Error Handling with Retry theme={null} import time def get_snippet_with_retry(snippet_id, max_retries=3): for attempt in range(max_retries): try: return get_snippet(snippet_id) except requests.exceptions.HTTPError as e: if e.response.status_code == 429: # Rate limit - wait and retry retry_after = int(e.response.headers.get('Retry-After', 60)) if attempt < max_retries - 1: print(f'Rate limited. Waiting {retry_after}s...') time.sleep(retry_after) continue elif e.response.status_code == 404: print(f'Snippet {snippet_id} not found') return None elif e.response.status_code in [401, 403]: print(f'Authentication/permission error') raise else: raise raise Exception('Max retries exceeded') ``` ## Common Issues **Problem**: The snippet ID doesn't exist or was deleted. **Solution**: * Verify the snippet ID is correct * Check if the snippet was deleted * Ensure the snippet belongs to your workspace {' '} **Problem**: Your API key doesn't have access to the snippet's team. **Solution**: - Check your API key's team permissions - Ensure the API key has access to the required team - Verify your workspace subscription is active **Problem**: Invalid or missing API key. **Solution**: * Check the Authorization header is properly formatted * Verify your API key is active * Ensure you're using `Bearer YOUR_API_KEY` format ## Best Practices **Use caching** for frequently accessed snippets to reduce API calls **Implement error handling** for all possible error scenarios **Store snippet IDs** persistently to avoid lookup operations **Monitor usage** through the response's usage field **Validate IDs** before making requests to avoid unnecessary API calls Don't fetch snippets in tight loops without caching - this will quickly exhaust your API quota and hit rate limits. ## Related Endpoints * [Get Multiple Snippets](/api-reference/snippets/get-snippets) - Fetch multiple snippets at once * [Create Snippet](/api-reference/snippets/create-snippet) - Create a new snippet * [Update Snippet](/api-reference/snippets/update-snippet) - Update an existing snippet * [Get Snippet Variation](/api-reference/variations/get-variation) - Get a specific variation # Get Multiple Snippets Source: https://docs.getsnippets.ai/api-reference/snippets/get-snippets GET /snippets Retrieves multiple snippets by their IDs. API Cost: N requests (one per accessible snippet). # Update Snippet Source: https://docs.getsnippets.ai/api-reference/snippets/update-snippet PUT /snippet Updates an existing snippet. API Cost: 1 request. # Create Tag Source: https://docs.getsnippets.ai/api-reference/tags/create-tag POST /tag Creates a new tag. API Cost: 1 request. # Create Multiple Tags Source: https://docs.getsnippets.ai/api-reference/tags/create-tags POST /tags Creates multiple tags in a single request. API Cost: N requests (one per tag). # Delete Tag Source: https://docs.getsnippets.ai/api-reference/tags/delete-tag DELETE /tag Deletes a tag and its associations with snippets. API Cost: 1 request. # Delete Multiple Tags Source: https://docs.getsnippets.ai/api-reference/tags/delete-tags DELETE /tags Deletes multiple tags by their IDs. API Cost: N requests (one per tag). # Get Tag Source: https://docs.getsnippets.ai/api-reference/tags/get-tag GET /tag Retrieves a tag's metadata and its associated snippets. API Cost: 1 + N requests (1 for tag + N for snippets). # Get Multiple Tags Source: https://docs.getsnippets.ai/api-reference/tags/get-tags GET /tags Retrieves multiple tags by their IDs. API Cost: N requests (one per accessible tag). # Update Tag Source: https://docs.getsnippets.ai/api-reference/tags/update-tag PUT /tag Updates an existing tag. API Cost: 1 request. # Update Multiple Tags Source: https://docs.getsnippets.ai/api-reference/tags/update-tags PUT /tags Updates multiple tags in a single request. API Cost: N requests (one per tag). # Usage & Billing Source: https://docs.getsnippets.ai/api-reference/usage-billing Understand API usage costs and billing ## Pricing Overview The Snippets AI API uses a simple, transparent pricing model: **\$10 USD per 100,000 requests** Pay only for what you use with no hidden fees ### What Counts as a Request? Each API call counts toward your usage quota. The cost varies by endpoint: * **Single resource operations**: 1 request (GET, POST, PUT, DELETE one item) * **Batch operations**: N requests (where N = number of items processed) * **Paginated operations**: 1 + N requests (1 for metadata + N for items returned) ## Request Costs by Endpoint ### Snippets Fetch a single snippet Create a new snippet Update a snippet Delete a snippet Fetch multiple snippets - costs 1 request per accessible snippet Create multiple snippets - costs 1 request per snippet created Delete multiple snippets - costs 1 request per accessible snippet deleted ### Variations Fetch a single variation Update a variation Delete variation(s) - costs 1 request per variation deleted Get version history - costs 1 request per history record returned ### Folders Get folder with snippets - costs 1 request for folder + 1 per snippet returned Create a folder Update a folder Delete a folder (contained snippets are orphaned) Get multiple folders - costs M requests for folders + N for total snippets Create multiple folders - costs 1 request per folder Update multiple folders - costs 1 request per folder Delete multiple folders - costs 1 request per folder ### Tags Get tag with snippets - costs 1 request for tag + 1 per snippet returned Create a tag Update a tag Delete a tag Get multiple tags - costs 1 request per accessible tag Create multiple tags - costs 1 request per tag Update multiple tags - costs 1 request per tag Delete multiple tags - costs 1 request per tag ## Understanding Request Costs ### Single Operations (1 Request) Simple operations on single resources always cost 1 request: ```javascript theme={null} // Cost: 1 request const snippet = await api.get('/snippet', { params: { id: 'snippet_uuid' }, }); // Cost: 1 request const result = await api.post('/folder', { folderName: 'My Folder', folderColor: '#3B82F6', teamId: 'team_uuid', }); ``` ### Batch Operations (N Requests) Batch operations cost N requests, where N is the number of items: ```javascript theme={null} // Cost: 10 requests (one per snippet) const snippets = await api.get('/snippets', { params: { ids: '["id1", "id2", ..., "id10"]' }, }); // Cost: 5 requests (one per folder created) const result = await api.post('/folders', { folders: [ /* 5 folder objects */ ], }); ``` ### Paginated Operations (1 + N Requests) Operations that return a resource plus a list of items: ```javascript theme={null} // Cost: 1 (folder) + 20 (snippets) = 21 requests const folder = await api.get('/folder', { params: { folderId: 'folder_uuid', limit: 20, // Returns up to 20 snippets }, }); // To minimize costs, use smaller limit values: // Cost: 1 + 5 = 6 requests const folder = await api.get('/folder', { params: { folderId: 'folder_uuid', limit: 5, // Returns only 5 snippets }, }); ``` ## Checking Your Usage Every API response includes usage information: ```json theme={null} { "success": true, "data": { /* response data */ }, "usage": { "remainingRequests": 99750 } } ``` For batch operations, you also get cost details: ```json theme={null} { "success": true, "data": { /* response data */ }, "usage": { "remainingRequests": 99750, "usageDeducted": 250 }, "metadata": { "requestedCount": 250, "accessibleCount": 250 } } ``` ## Cost Optimization Strategies While batch endpoints are convenient, they can be expensive. Optimize by: ```javascript theme={null} // ❌ Expensive: Fetching 1000 snippets // Cost: 1000 requests const result = await api.get('/snippets', { params: { ids: thousandSnippetIds } }); // βœ… Better: Fetch only what you need // Cost: 10 requests const result = await api.get('/snippets', { params: { ids: tenMostRecentIds } }); // βœ… Best: Use pagination to spread costs // Cost: 1 + 10 = 11 requests const folder = await api.get('/folder', { params: { folderId: 'id', limit: 10, offset: 0 } }); ``` Reduce API calls by caching frequently accessed data: ```javascript theme={null} class SnippetCache { constructor(ttl = 5 * 60 * 1000) { // 5 minutes this.cache = new Map(); this.ttl = ttl; } async get(id) { const cached = this.cache.get(id); if (cached && Date.now() - cached.timestamp < this.ttl) { console.log('Cache hit - saved 1 request'); return cached.data; } // Cache miss - fetch from API const data = await fetchSnippet(id); this.cache.set(id, { data, timestamp: Date.now() }); return data; } invalidate(id) { this.cache.delete(id); } } ``` When fetching folders or tags with snippets, use appropriate pagination: ```javascript theme={null} // ❌ Expensive: Fetch all snippets at once // If folder has 1000 snippets, cost: 1 + 1000 = 1001 requests const folder = await api.get('/folder', { params: { folderId: 'id', limit: 100 } // max limit }); // βœ… Efficient: Fetch only what's needed for UI // Cost: 1 + 20 = 21 requests const folder = await api.get('/folder', { params: { folderId: 'id', limit: 20 } // show 20 per page }); // Load more on demand const nextPage = await api.get('/folder', { params: { folderId: 'id', limit: 20, offset: 20 } }); ``` Version history can be expensive if not limited: ```javascript theme={null} // ❌ Expensive: Fetch all history // If variation has 500 versions, cost: 500 requests const history = await api.get('/snippet/variation/history', { params: { variationId: 'id' } // no limit }); // βœ… Efficient: Limit history records // Cost: 10 requests const history = await api.get('/snippet/variation/history', { params: { variationId: 'id', limit: 10 // Only last 10 versions } }); // βœ… Even better: Use date filtering // Cost: ~5 requests (only recent changes) const history = await api.get('/snippet/variation/history', { params: { variationId: 'id', fromDate: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString(), limit: 100 } }); ``` Don't use batch endpoints if you only need a few items: ```javascript theme={null} // ❌ Wasteful: Using batch endpoint for 1-2 items // Cost: 2 requests const result = await api.get('/snippets', { params: { ids: 'id1,id2' } }); // βœ… Efficient: Use single endpoint // Cost: 2 requests (same cost, but simpler) const snippet1 = await api.get('/snippet', { params: { id: 'id1' }}); const snippet2 = await api.get('/snippet', { params: { id: 'id2' }}); // βœ… When batch makes sense (10+ items) // Much better than 50 individual calls const result = await api.get('/snippets', { params: { ids: fiftyIds } }); ``` ## Billing Examples ### Example 1: Small Project **Monthly Usage:** * 5,000 snippet fetches * 200 snippet creates * 100 snippet updates * 1,000 folder fetches with 10 snippets each **Total Requests:** * Snippets: 5,000 + 200 + 100 = 5,300 * Folders: 1,000 Γ— (1 + 10) = 11,000 * **Total: 16,300 requests** **Cost:** $10 Γ— (16,300 / 100,000) = **$1.63/month\*\* ### Example 2: Medium Integration **Monthly Usage:** * 50,000 snippet fetches * 5,000 snippet creates * 10,000 snippet updates * 5,000 variation fetches * 2,000 folder operations **Total Requests:** * Snippets: 50,000 + 5,000 + 10,000 = 65,000 * Variations: 5,000 * Folders: 2,000 * **Total: 72,000 requests** **Cost:** $10 Γ— (72,000 / 100,000) = **$7.20/month\*\* ### Example 3: High-Volume Application **Monthly Usage:** * 500,000 snippet operations * 100,000 variation operations * 50,000 folder/tag operations **Total Requests: 650,000** **Cost:** $10 Γ— (650,000 / 100,000) = **$65/month\*\* ## Monitoring Usage ### In Your Dashboard Monitor your API usage in real-time: 1. Navigate to **Settings** β†’ **API Usage** 2. View current billing period usage 3. See breakdown by endpoint 4. Track daily/weekly trends 5. Set usage alerts ### In API Responses Track usage programmatically: ```javascript theme={null} class UsageTracker { constructor() { this.totalRequests = 0; this.requestsByEndpoint = {}; } track(response, endpoint) { const deducted = response.usage?.usageDeducted || 1; this.totalRequests += deducted; this.requestsByEndpoint[endpoint] = (this.requestsByEndpoint[endpoint] || 0) + deducted; console.log(`Total requests this session: ${this.totalRequests}`); console.log(`Remaining quota: ${response.usage?.remainingRequests}`); // Alert if approaching limit if (response.usage?.remainingRequests < 1000) { this.alertLowQuota(response.usage.remainingRequests); } } alertLowQuota(remaining) { console.warn(`⚠️ Low API quota: ${remaining} requests remaining`); } getSummary() { return { total: this.totalRequests, byEndpoint: this.requestsByEndpoint, estimatedCost: (this.totalRequests / 100000) * 10, }; } } // Usage const tracker = new UsageTracker(); const response = await api.get('/snippet', { params: { id: 'id' } }); tracker.track(response.data, '/snippet'); // Get summary console.log(tracker.getSummary()); // { // total: 125, // byEndpoint: { '/snippet': 100, '/folder': 25 }, // estimatedCost: 0.0125 // } ``` ## Billing Cycle * **Billing Period**: Monthly (from the 1st to the last day of each month) * **Usage Reset**: Quota resets on the 1st of each month * **Payment**: Automatic charge on the 1st for previous month's usage * **Minimum Charge**: No minimum - pay only for what you use ## Handling Insufficient Quota When you run out of API requests, you'll receive a `403 Forbidden` error: ```json theme={null} { "success": false, "message": "Insufficient API requests. This operation requires 5 requests but you have 0 remaining.", "usage": { "remainingRequests": 0, "requiredRequests": 5 } } ``` **Options:** 1. Wait until the next billing cycle (auto-refill on the 1st) 2. Purchase additional request packages 3. Upgrade to a higher plan with larger included quota ## Purchasing Additional Requests Need more requests before your cycle resets? Navigate to **Admin** β†’ **API Access** Click **Add** Choose package size (100K, 500K, 1M requests) Complete payment - requests added immediately ## Enterprise Pricing For high-volume applications, we offer custom enterprise plans: Higher rate limits and request quotas 24/7 support with SLA guarantees Discuss enterprise pricing for your organization ## FAQs Yes, all authenticated requests count toward your quota, including those that return errors. However, if a request fails due to rate limiting (429), it does not count as an additional request. {' '} Once you've used all your API requests for the billing period, you'll receive `403 Forbidden` errors until you purchase additional requests or your quota resets on the 1st of the next month. {' '} No, unused requests do not roll over to the next billing period. We recommend monitoring your usage to right-size your plan. {' '} {' '} Currently, all API usage is billed. However, new workspaces receive an initial credit to test the API. Contact sales for evaluation credits. ## Need Help? Discuss custom pricing # Delete Variation Source: https://docs.getsnippets.ai/api-reference/variations/delete-variation DELETE /snippet/variation Deletes one or more variations. Can delete a single variation via query parameter or multiple via request body. API Cost: N requests (one per variation). Note: Snippets must have at least one variation. # Get Variation History Source: https://docs.getsnippets.ai/api-reference/variations/get-history GET /snippet/variation/history Retrieves the version history of a snippet variation. API Cost: N requests (one per history record returned). # Get Variation Source: https://docs.getsnippets.ai/api-reference/variations/get-variation GET /snippet/variation Retrieves a specific variation of a snippet. API Cost: 1 request. # Update Variation Source: https://docs.getsnippets.ai/api-reference/variations/update-variation PUT /snippet/variation Updates a specific variation. API Cost: 1 request. # Audio Preview in Snippets Source: https://docs.getsnippets.ai/guides/audio-preview Preview and play audio attachments directly in snippet view ## Overview Audio Preview lets you listen to voice recordings and audio attachments directly within snippets-no need to download or open external players. Whether you've recorded a voice note, attached an audio explanation, or saved a podcast clip, Audio Preview makes it instantly accessible with built-in playback controls. This feature transforms snippets from text-only into rich, multimedia knowledge bases. ## Why Audio Preview Matters Audio adds context that text alone can't capture: * **Tone & Emphasis**: Hear how something should be delivered * **Faster Creation**: Speak instead of type (much faster) * **Accessibility**: Alternative format for different learning styles * **Nuance**: Explain complex concepts verbally * **Multilingual**: Pronunciation guides, language learning ## How It Works