Cron & External AI APIs
Schedule cron jobs in cPanel that call external AI APIs — like OpenAI, Anthropic Claude, or Google Gemini — to automate content generation, email summaries, and other repetitive tasks without taxing your shared hosting resources.
How It Works
The idea is simple: a lightweight PHP script on your server sends a request to an external AI API, receives the response, and does something useful with it (saves a file, inserts a database row, sends an email). You then use a cPanel cron job to run that script on a schedule. The AI processing happens entirely on the API provider's servers, so your hosting account only handles the small HTTP request and response.
Step 1: Store Your API Key Securely
API keys are sensitive credentials. Never place them inside your public_html directory where they could be exposed to the web. Instead, create a configuration file one level above your web root.
- In cPanel, open File Manager.
- Navigate to your home directory (
/home/username/), not intopublic_html. - Create a new file called
ai-config.php. - Add your API keys to the file:
<?php
// /home/username/ai-config.php
// This file is OUTSIDE public_html and cannot be accessed via the web.
return [
'openai_api_key' => 'sk-proj-YOUR_OPENAI_KEY_HERE',
'anthropic_api_key' => 'sk-ant-YOUR_ANTHROPIC_KEY_HERE',
'from_email' => 'you@yourdomain.com',
'to_email' => 'you@yourdomain.com',
];
public_html. If a key is compromised, regenerate it immediately from your API provider's dashboard.
Step 2: Create a PHP Script That Calls an AI API
Below is a practical example: a script that asks an AI API to generate a short blog post and saves it as an HTML file in your site's content directory.
Example: Generate Content with OpenAI
<?php
// /home/username/cron-scripts/generate-content.php
$config = require '/home/username/ai-config.php';
// Define the prompt
$topic = 'Tips for speeding up your WordPress site';
$prompt = "Write a short, helpful blog post (around 200 words) about: $topic. "
. "Return only the HTML body content with h2 and p tags. No doctype or head.";
// Build the API request
$data = json_encode([
'model' => 'gpt-4o-mini',
'messages' => [
['role' => 'system', 'content' => 'You are a helpful web hosting blog writer.'],
['role' => 'user', 'content' => $prompt],
],
'max_tokens' => 500,
]);
$ch = curl_init('https://api.openai.com/v1/chat/completions');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $data,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Authorization: Bearer ' . $config['openai_api_key'],
],
CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200) {
echo "API request failed with HTTP $httpCode\n";
echo $response . "\n";
exit(1);
}
$result = json_decode($response, true);
$content = $result['choices'][0]['message']['content'] ?? '';
if (empty($content)) {
echo "No content returned from API.\n";
exit(1);
}
// Save the generated content
$filename = '/home/username/public_html/blog/ai-post-' . date('Y-m-d') . '.html';
file_put_contents($filename, $content);
echo "Content saved to $filename\n";
Example: Daily Summary Email with Claude
This script reads a log file, sends it to the Anthropic API for summarization, and emails you the result.
<?php
// /home/username/cron-scripts/daily-summary.php
$config = require '/home/username/ai-config.php';
// Read yesterday's access log excerpt (last 200 lines)
$logFile = '/home/username/access-logs/yourdomain.com';
$logLines = array_slice(file($logFile, FILE_IGNORE_NEW_LINES), -200);
$logText = implode("\n", $logLines);
// Ask Claude to summarize the traffic
$data = json_encode([
'model' => 'claude-sonnet-4-20250514',
'max_tokens' => 600,
'messages' => [
[
'role' => 'user',
'content' => "Summarize this web server access log into a brief daily report. "
. "Include: total requests, top 5 pages, any unusual activity or errors.\n\n"
. $logText,
],
],
]);
$ch = curl_init('https://api.anthropic.com/v1/messages');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $data,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'x-api-key: ' . $config['anthropic_api_key'],
'anthropic-version: 2023-06-01',
],
CURLOPT_TIMEOUT => 60,
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200) {
echo "Anthropic API error: HTTP $httpCode\n";
exit(1);
}
$result = json_decode($response, true);
$summary = $result['content'][0]['text'] ?? 'No summary generated.';
// Send the summary by email
$subject = 'Daily Site Summary - ' . date('M j, Y');
$headers = "From: {$config['from_email']}\r\n"
. "Content-Type: text/plain; charset=UTF-8\r\n";
mail($config['to_email'], $subject, $summary, $headers);
echo "Summary email sent.\n";
Step 3: Set Up the Cron Schedule in cPanel
- Log into cPanel.
- Go to Advanced → Cron Jobs.
- For the content generation script, set the schedule to once per day (e.g., 6:00 AM):
- Minute:
0 - Hour:
6 - Day / Month / Weekday:
*
- Minute:
- Enter the command:
/usr/local/bin/php /home/username/cron-scripts/generate-content.php - Click Add New Cron Job.
- Repeat for the daily summary script, using a different time (e.g., 11:55 PM):
/usr/local/bin/php /home/username/cron-scripts/daily-summary.php
username with your actual cPanel username in all file paths. You can find your username in cPanel under General Information on the right side of the dashboard.
Organizing Your Cron Scripts
Keep your cron scripts outside of public_html so they cannot be triggered by web visitors. A recommended directory structure:
/home/username/
ai-config.php ← API keys (outside public_html)
cron-scripts/
generate-content.php ← Content generation script
daily-summary.php ← Daily summary script
public_html/ ← Your website files
blog/
ai-post-2026-04-16.html
API Rate Limits and Costs
- Start with longer intervals — Run jobs once or twice daily rather than every hour while you test. A script running every 5 minutes can make 288 API calls per day.
- Use cheaper models for simple tasks — Models like
gpt-4o-miniorclaude-haikucost a fraction of their larger counterparts and are fine for summaries and short content. - Set max_tokens conservatively — Limit the response size to what you actually need. There is no reason to request 4,000 tokens if 500 will do.
- Add error handling — If an API returns a rate-limit error (HTTP 429), log it and exit gracefully rather than retrying in a loop.
- Monitor your API dashboard — Check your OpenAI, Anthropic, or other provider's usage dashboard regularly to track costs.
Monitoring Cron Output via Email
Use echo statements in your scripts to output useful information:
- Whether the API call succeeded or failed
- The HTTP status code from the API
- The file path where content was saved
- Any error messages
Once your scripts are running reliably and you no longer need the emails, you can suppress output by appending >/dev/null 2>&1 to the cron command.
Troubleshooting
- "Permission denied" errors — Make sure your script files are readable by your user. In File Manager, right-click the file, choose Change Permissions, and set to
644. - API timeouts — Some AI APIs can be slow during peak hours. Increase the
CURLOPT_TIMEOUTvalue to 60 or 90 seconds. If timeouts persist, schedule jobs during off-peak hours (early morning or late night). - "curl_exec() has been disabled" — This is uncommon on Ultra Web Hosting but can happen. Contact support if you see this error.
- Empty responses — Always check that the response body is not empty before processing it. Log the raw response for debugging.
- Script works in browser but not in cron — Cron runs scripts without a web context. Make sure you use full file paths (not relative paths) and do not rely on
$_SERVERvariables.