MENU navbar-image

Introduction

API endpoints for fetching content sources and generating AI-powered articles via PostFuel.

Welcome to the PostFuel API! This API allows you to fetch content from various sources and generate AI articles programmatically.

<aside>Use the navigation on the left to explore available endpoints. Code examples are provided in the dark panel on the right.</aside>

### Authentication
Most endpoints require authentication using a Bearer token. Generate your API token from your account settings page and include it in the `Authorization` header:

`Authorization: Bearer {YOUR_API_TOKEN}`

Authenticating requests

To authenticate requests, include a Authorization header with the value "Bearer {YOUR_API_TOKEN}".

All authenticated endpoints are marked with a requires authentication badge in the documentation below.

Enter your token with the "Bearer " prefix. You can generate API tokens from your dashboard settings under API Tokens.

Content Fetching

Fetch Content Posts

requires authentication

Retrieves a list of recent content items (news articles, local places) based on a topic/query from the specified source. Results are cached temporarily.

This endpoint requires authentication and consumes credits based on the source (for subscribed users) or checks monthly free usage limits (for non-subscribed users).

Example request:
curl --request POST \
    "https://postfuel.dev/api/fetch-posts" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"source\": \"\\\"google_news\\\" Enum(\\\"google_news\\\", \\\"google_local_search\\\")\",
    \"topic\": \"\\\"AI advancements\\\"\",
    \"limit\": 5,
    \"after\": null,
    \"country\": \"\\\"us\\\"\"
}"
const url = new URL(
    "https://postfuel.dev/api/fetch-posts"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "source": "\"google_news\" Enum(\"google_news\", \"google_local_search\")",
    "topic": "\"AI advancements\"",
    "limit": 5,
    "after": null,
    "country": "\"us\""
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://postfuel.dev/api/fetch-posts';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'source' => '"google_news" Enum("google_news", "google_local_search")',
            'topic' => '"AI advancements"',
            'limit' => 5,
            'after' => null,
            'country' => '"us"',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "posts": [
        {
            "title": "Example News Title",
            "summary": "A snippet or description of the content...",
            "url": "https://example.com/news-article",
            "source": "google_news",
            "source_meta": {
                "id": "md5_hash_of_url",
                "news_source": "Example News Outlet",
                "published_date": "1 day ago",
                "link_url": "https://example.com/news-article"
            },
            "comments": []
        },
        {
            "title": "Example Cafe",
            "summary": "Cozy spot with great espresso.",
            "url": "https://examplecafe.com",
            "source": "google_local_search",
            "source_meta": {
                "id": "md5_hash_of_title_address",
                "local_address": "123 Main St, Halifax",
                "local_type": "Coffee shop",
                "local_rating": "4.5",
                "local_reviews": "150",
                "link_url": "https://examplecafe.com"
            },
            "comments": []
        }
    ],
    "after": null,
    "result_summary_text": "Example News Title, Example Cafe"
}
 

Example response (401, Unauthenticated):


{
    "message": "Unauthenticated."
}
 

Example response (402, Insufficient Credits (Paid User)):


{
    "error": "Insufficient credits.",
    "message": "This request requires 14 credits, but you only have 10 available."
}
 

Example response (403, Forbidden (Free User - Invalid Source/Action)):


{
    "message": "Subscription Required.",
    "error": "This feature or model requires an active paid subscription."
}
 

Example response (422, Validation Error):


{
    "message": "The given data was invalid.",
    "errors": {
        "format": [
            "The selected format is invalid."
        ],
        "openai_model": [
            "Invalid OpenAI model specified. Allowed models are: gpt-4.1, gpt-4.1-mini, gpt-4.1-nano."
        ]
    }
}
 

Example response (429, Free Tier Limit Reached):


{
    "message": "Free Limit Reached.",
    "error": "You have reached your monthly limit for this free action. Please upgrade for continued access."
}
 

Example response (500, Server Error):


{
    "message": "An internal server error occurred.",
    "error": "Failed to process request due to an unexpected issue. Please try again later or contact support if the problem persists."
}
 

Request      

POST api/fetch-posts

Headers

Authorization      

Example: Bearer {YOUR_API_TOKEN}

Content-Type      

Example: application/json

Body Parameters

source   string   

The source service to fetch from. Example: "google_news" Enum("google_news", "google_local_search")

topic   string   

The search keywords or query. For google_local_search, include the location within this query (e.g., "coffee shops in Halifax"). Example: "AI advancements"

limit   integer  optional  

optional Maximum number of posts/results to return (1-20). Defaults to 10. Example: 5

after   string  optional  

optional Pagination cursor/token (currently not supported by active sources).

country   string  optional  

optional The 2-letter country code (ISO 3166-1 alpha-2) to search within. Applies only to google_news source. Defaults to 'us' (United States) if omitted. Example: "us"

Content Generation

Queue Content Generation [v1.1 - Flexible Prompting]

requires authentication

Accepts parameters to define content generation requirements, offering flexible control via presets, structured guidance, or detailed prompts. Requires either manual_prompt OR (source_ref_service + source_ref_id) as the base input topic/source.

Prompting Hierarchy:

  1. generation_preset (Easy Mode): If provided (and not 'none'), uses an optimized internal template. Takes highest priority.
  2. guidance (Guided Mode): If no preset, uses structured JSON input to build the prompt. Takes priority over focus_prompt.
  3. focus_prompt (Expert Mode): If no preset and no guidance, uses the raw free-form prompt string.
  4. Fallback: If none of the above apply, uses a basic default structure.

Queues background jobs for scraping (if applicable/paid) and AI generation. Returns 202 Accepted immediately with request_id and batch_id. Poll the /api/results/{request_id} endpoint for status and final content. Requires authentication. Consumes credits or free tier limits. See parameter details generated by Scribe from the Request class.

Example request:
curl --request POST \
    "https://postfuel.dev/api/generate-preview" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"source_ref_service\": \"google_news\",
    \"source_ref_id\": \"e647eb4609d5313d7e6bd4568311a5f0\",
    \"manual_prompt\": \"Benefits of Hyperlocal Marketing\",
    \"attached_urls\": [
        \"https:\\/\\/example.com\\/article1\"
    ],
    \"generation_preset\": \"blog_standard\",
    \"guidance\": {
        \"tone\": \"Professional\",
        \"target_audience\": \"Small Business Owners\"
    },
    \"focus_prompt\": \"Write a comprehensive blog post comparing A vs B...\",
    \"format\": \"default\",
    \"use_scraping\": false,
    \"include_quotes\": false,
    \"openai_model\": \"gpt-4.1-mini\",
    \"use_reddit_comments\": true,
    \"use_business_profile\": false
}"
const url = new URL(
    "https://postfuel.dev/api/generate-preview"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "source_ref_service": "google_news",
    "source_ref_id": "e647eb4609d5313d7e6bd4568311a5f0",
    "manual_prompt": "Benefits of Hyperlocal Marketing",
    "attached_urls": [
        "https:\/\/example.com\/article1"
    ],
    "generation_preset": "blog_standard",
    "guidance": {
        "tone": "Professional",
        "target_audience": "Small Business Owners"
    },
    "focus_prompt": "Write a comprehensive blog post comparing A vs B...",
    "format": "default",
    "use_scraping": false,
    "include_quotes": false,
    "openai_model": "gpt-4.1-mini",
    "use_reddit_comments": true,
    "use_business_profile": false
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://postfuel.dev/api/generate-preview';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'source_ref_service' => 'google_news',
            'source_ref_id' => 'e647eb4609d5313d7e6bd4568311a5f0',
            'manual_prompt' => 'Benefits of Hyperlocal Marketing',
            'attached_urls' => [
                'https://example.com/article1',
            ],
            'generation_preset' => 'blog_standard',
            'guidance' => [
                'tone' => 'Professional',
                'target_audience' => 'Small Business Owners',
            ],
            'focus_prompt' => 'Write a comprehensive blog post comparing A vs B...',
            'format' => 'default',
            'use_scraping' => false,
            'include_quotes' => false,
            'openai_model' => 'gpt-4.1-mini',
            'use_reddit_comments' => true,
            'use_business_profile' => false,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (202, Request Accepted):


{
    "message": "Content generation request accepted and queued.",
    "request_id": "2c212ba1-e466-45dd-91bf-f296d486e641",
    "batch_id": "9eb2653b-96b7-40a1-a3d3-682f386867f5"
}
 

Example response (401, Unauthenticated):


{
    "message": "Unauthenticated."
}
 

Example response (402, Insufficient Credits):


{
    "error": "Insufficient credits.",
    "message": "This request requires 14 credits, but you only have 10 available."
}
 

Example response (403, Forbidden (e.g., Free User Paid Feature)):


{
    "message": "Subscription Required.",
    "error": "This feature or model requires an active paid subscription."
}
 

Example response (422, Validation Error):


{
    "message": "The given data was invalid.",
    "errors": {
        "format": [
            "The selected format is invalid."
        ],
        "openai_model": [
            "Invalid OpenAI model specified. Allowed models are: gpt-4.1, gpt-4.1-mini, gpt-4.1-nano."
        ]
    }
}
 

Example response (429, Rate Limited / Free Tier Limit Reached):


{
    "message": "Free Limit Reached.",
    "error": "You have reached your monthly limit for this free action. Please upgrade for continued access."
}
 

Example response (500, Server Error):


{
    "message": "An internal server error occurred.",
    "error": "Failed to process request due to an unexpected issue. Please try again later or contact support if the problem persists."
}
 

Request      

POST api/generate-preview

Headers

Authorization      

Example: Bearer {YOUR_API_TOKEN}

Content-Type      

Example: application/json

Body Parameters

source_ref_service   string  optional  

Input Method A (Source): The source service of a previously fetched post (google_news, google_local_search). Requires source_ref_id. This field is required when source_ref_id is present. Example: google_news

Must be one of:
  • google_news
  • google_local_search
source_ref_id   string  optional  

Input Method A (Source): The unique ID (source_meta.id) of a previously fetched post. Requires source_ref_service. This field is required when source_ref_service is present. Must not be greater than 255 characters. Example: e647eb4609d5313d7e6bd4568311a5f0

manual_prompt   string  optional  

Input Method B (Manual): Your primary topic or base instructions if not using source_ref_id. This text is often used as the {TOPIC} for generation_preset templates or context for guidance. This field is required when none of source_ref_id, generation_preset, guidance, and focus_prompt are present. Must not be greater than 5000 characters. Example: Benefits of Hyperlocal Marketing

attached_urls   string[]  optional  

A valid URL if attached_urls is used. This field is required when attached_urls is present. Must be a valid URL. Must not be greater than 2048 characters.

generation_preset   string  optional  

Guidance Method 1 (Easy Mode - Takes Priority): Select a pre-defined goal (preset name) for optimized output using an internal template. If set (and not 'none'), this method is used, and guidance / focus_prompt are ignored. Uses manual_prompt or source reference title as the core {TOPIC} for the template. Available presets:

  • blog_standard: Generates a standard, well-structured blog post with intro, body paragraphs, and conclusion.
  • benefit_listicle: Generates a listicle highlighting the key benefits of a topic.
  • social_thread_ideas: Generates multiple distinct ideas/angles for a social media thread (e.g., Twitter/Threads). Example: blog_standard
Must be one of:
  • none
  • blog_standard
  • benefit_listicle
  • social_thread_ideas
guidance   object  optional  

Guidance Method 2 (Guided Mode - Used if Preset is 'none'): Provide structured instructions as a JSON object (key-value pairs). Takes precedence over focus_prompt if provided. Common keys: target_audience (string), tone (string), key_points_to_include (array of strings), structure_hint (string), negative_keywords (array of strings), desired_length_words (integer).

focus_prompt   string  optional  

Guidance Method 3 (Expert Mode - Used if Preset is 'none' AND Guidance is empty): Provide your own detailed, free-form instructions and structural guidance for the AI. Offers maximum control but requires careful prompt engineering. Must not be greater than 2500 characters. Example: Write a comprehensive blog post comparing A vs B...

format   string   

Required: Hint for the desired base HTML output structure. Use custom if providing detailed structure via guidance or focus_prompt that requires specific tags beyond paragraphs or standard lists. Example: default

Must be one of:
  • default
  • listicle
  • interview
  • custom
use_scraping   boolean  optional  

Optional: Attempt to scrape content from attached_urls and/or the external URL in a referenced post? Requires paid subscription. Defaults to true. Set to false to prevent scraping even if URLs are present. Example: false

include_quotes   boolean  optional  

Optional: Allow AI to include generic quotes from scraped text (if use_scraping is true and text is found)? Defaults to true. Example: false

openai_model   string   

Required: The OpenAI model ID to use. Free tier users are restricted to 'gpt-4.1-nano'.. Example: gpt-4.1-mini

Must be one of:
  • gpt-4.1
  • gpt-4.1-mini
  • gpt-4.1-nano
use_reddit_comments   boolean  optional  

Example: true

use_business_profile   boolean  optional  

Optional: If a business profile exists for your account, setting this to true (default if profile exists and is complete) will use its insights to tailor the generated content. Set to false to ignore the business profile for this request. Example: false

Results

Get Content Generation Result

requires authentication

Retrieves the status and results (including generated content, title options, tags, and context suggestions) for a previously submitted content generation request, identified by its unique requestId. Poll this endpoint until the status is 'completed' or 'failed'.

Example request:
curl --request GET \
    --get "https://postfuel.dev/api/results/&quot;fd86d066-e784-4c1e-9c10-9d888003620f&quot;" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"request_id\": \"66529e01-d113-3473-8d6f-9e11e09332ea\"
}"
const url = new URL(
    "https://postfuel.dev/api/results/&quot;fd86d066-e784-4c1e-9c10-9d888003620f&quot;"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "request_id": "66529e01-d113-3473-8d6f-9e11e09332ea"
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://postfuel.dev/api/results/"fd86d066-e784-4c1e-9c10-9d888003620f"';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'request_id' => '66529e01-d113-3473-8d6f-9e11e09332ea',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200, Completed):


{
"request_id": "fd86d066-e784-4c1e-9c10-9d888003620f",
"status": "completed",
"created_at": "2025-04-25T15:27:18.000000Z",
"completed_at": "2025-04-25T15:27:45.000000Z",
"results": {
"title_suggestions": [
"Headline Option 1: Generated Title One",
"Headline Option 2: Generated Title Two",
"Headline Option 3: Generated Title Three"
],
"generated_content_html": "<p>This is the generated article content...</p><p>More content...</p>",
"suggested_tags": ["api", "laravel", "content generation"],
},
"error": null
}
 

Example response (200, Processing):


{
    "request_id": "fd86d066-e784-4c1e-9c10-9d888003620f",
    "status": "processing",
    "created_at": "2025-04-25T15:27:18.000000Z",
    "completed_at": null,
    "results": null,
    "error": null
}
 

Example response (200, Failed):


{
    "request_id": "fd86d066-e784-4c1e-9c10-9d888003620f",
    "status": "failed",
    "created_at": "2025-04-25T15:27:18.000000Z",
    "completed_at": "2025-04-25T15:27:25.000000Z",
    "results": null,
    "error": "AI service request failed. Status: 500"
}
 

Example response (400, Invalid Request ID Format):


{
    "error": "API key/credentials not found for the specified source.",
    "message": "Please add your credentials for 'currents' in your account settings.",
    "source": "currents"
}
 

Example response (401, Unauthenticated):


{
    "message": "Unauthenticated."
}
 

Example response (404, Not Found (Wrong ID or Not Owner)):


{
    "message": "Generation result not found."
}
 

Request      

GET api/results/{requestId}

Headers

Authorization      

Example: Bearer {YOUR_API_TOKEN}

Content-Type      

Example: application/json

URL Parameters

requestId   string   

The UUID of the generation request (returned by /generate-preview). Example: "fd86d066-e784-4c1e-9c10-9d888003620f"

Body Parameters

request_id   string   

Must be a valid UUID. Example: 66529e01-d113-3473-8d6f-9e11e09332ea

Business Profile Management

Create or Request Generation of a Business Profile.

requires authentication

This endpoint initiates the process of creating or regenerating a business profile. If it's the first time, or if regeneration is requested, it will queue jobs for scraping provided URLs and then generating AI insights.

The first generation of a business profile for a user is typically free. Subsequent regenerations may incur credit costs.

Example request:
curl --request POST \
    "https://postfuel.dev/api/business-profile" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"business_name\": \"Acme Innovations Inc.\",
    \"user_provided_description\": \"Acme Innovations Inc. is a software development company specializing in AI-driven solutions for small to medium-sized businesses. We aim to help companies automate their workflows and gain better insights from their data. Our target audience includes marketing agencies, e-commerce platforms, and SaaS providers.\",
    \"user_provided_urls\": [
        \"https:\\/\\/example.com\\/products\"
    ]
}"
const url = new URL(
    "https://postfuel.dev/api/business-profile"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "business_name": "Acme Innovations Inc.",
    "user_provided_description": "Acme Innovations Inc. is a software development company specializing in AI-driven solutions for small to medium-sized businesses. We aim to help companies automate their workflows and gain better insights from their data. Our target audience includes marketing agencies, e-commerce platforms, and SaaS providers.",
    "user_provided_urls": [
        "https:\/\/example.com\/products"
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://postfuel.dev/api/business-profile';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'business_name' => 'Acme Innovations Inc.',
            'user_provided_description' => 'Acme Innovations Inc. is a software development company specializing in AI-driven solutions for small to medium-sized businesses. We aim to help companies automate their workflows and gain better insights from their data. Our target audience includes marketing agencies, e-commerce platforms, and SaaS providers.',
            'user_provided_urls' => [
                'https://example.com/products',
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (202, Request Accepted for Generation):


{
    "message": "Business profile generation request accepted and queued.",
    "business_profile_id": "uuid-of-the-profile",
    "batch_id": "uuid-of-the-batch"
}
 

Example response (400, Bad Request (e.g., No URLs for initial scrape if required and no description)):



 

Example response (401, Unauthenticated):


{
    "message": "Unauthenticated."
}
 

Example response (402, Insufficient Credits (for regeneration)):


{
    "error": "Insufficient credits.",
    "message": "This request requires 14 credits, but you only have 10 available."
}
 

Example response (403, Forbidden):


{
    "message": "Subscription Required.",
    "error": "This feature or model requires an active paid subscription."
}
 

Example response (422, Validation Error):


{
    "message": "The given data was invalid.",
    "errors": {
        "format": [
            "The selected format is invalid."
        ],
        "openai_model": [
            "Invalid OpenAI model specified. Allowed models are: gpt-4.1, gpt-4.1-mini, gpt-4.1-nano."
        ]
    }
}
 

Example response (500, Server Error):


{
    "message": "An internal server error occurred.",
    "error": "Failed to process request due to an unexpected issue. Please try again later or contact support if the problem persists."
}
 

Request      

POST api/business-profile

Headers

Authorization      

Example: Bearer {YOUR_API_TOKEN}

Content-Type      

Example: application/json

Body Parameters

business_name   string  optional  

Optional: The name of your business. Must not be greater than 255 characters. Example: Acme Innovations Inc.

user_provided_description   string   

Required: A detailed description of your business, its activities, target audience, and goals. Must be at least 50 characters. Must not be greater than 10000 characters. Example: Acme Innovations Inc. is a software development company specializing in AI-driven solutions for small to medium-sized businesses. We aim to help companies automate their workflows and gain better insights from their data. Our target audience includes marketing agencies, e-commerce platforms, and SaaS providers.

user_provided_urls   string[]  optional  

A valid URL if user_provided_urls is used. This field is required when user_provided_urls is present. Must be a valid URL. Must not be greater than 2048 characters.

Display the authenticated user's Business Profile.

requires authentication

Retrieves and returns the current business profile associated with the authenticated user.

Example request:
curl --request GET \
    --get "https://postfuel.dev/api/business-profile" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}"
const url = new URL(
    "https://postfuel.dev/api/business-profile"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://postfuel.dev/api/business-profile';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_TOKEN}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200, Successful Profile Retrieval):


{
    "data": {
        "id": "9c3b4a5e-6d7f-8a9b-0c1d-2e3f4a5b6c7d",
        "user_id": 1,
        "business_name": "Acme Web Solutions",
        "user_provided_description": "Acme Web Solutions builds innovative web applications for startups using Laravel and AI. We focus on delivering scalable and maintainable solutions.",
        "user_provided_urls": [
            "https://acmeweb.example.com",
            "https://acmeweb.example.com/services"
        ],
        "ai_generated_business_summary": "Acme Web Solutions is a development agency specializing in Laravel and AI-driven web applications targeting startup clients, aiming to provide scalable tech solutions.",
        "ai_generated_target_audience_description": "Primarily targets tech startups and entrepreneurs needing custom web application development, particularly those interested in leveraging AI.",
        "ai_generated_key_products_services_offered": [
            "Custom Web Application Development",
            "Laravel Development",
            "AI Integration Services",
            "Startup Technology Consulting"
        ],
        "ai_generated_unique_selling_propositions_usp": [
            "Specialization in Laravel & AI for Startups",
            "Focus on Scalable Solutions",
            "Agile Development Process"
        ],
        "ai_generated_brand_voice_and_tone_suggestion": "Professional & Authoritative",
        "ai_generated_core_business_goals_inferred": [
            "Acquire Startup Clients",
            "Deliver High-Quality Web Apps",
            "Establish Expertise in AI/Laravel Niche"
        ],
        "seo_profile": {
            "primary_keywords_identified": [
                "laravel development",
                "ai web applications",
                "startup web development",
                "custom web apps",
                "scalable solutions"
            ],
            "suggested_long_tail_keywords": [
                "laravel ai integration for startups",
                "custom laravel development agency",
                "scalable web apps for saas startups"
            ],
            "content_themes_identified": [
                "Laravel Framework",
                "AI in Web Development",
                "Startup Technology",
                "Web Application Scalability"
            ],
            "strengths_observed": "Website content clearly outlines specialization in Laravel and AI solutions targeting the startup sector.",
            "areas_for_improvement_suggestions": "Consider creating blog content or case studies focusing on specific AI integrations or successful startup projects."
        },
        "generation_status": "completed",
        "last_generated_at": "2025-05-06T10:00:00.000000Z",
        "error_message": null,
        "created_at": "2025-05-06T09:30:00.000000Z",
        "updated_at": "2025-05-06T10:00:00.000000Z"
    }
}
 

Example response (401, Unauthenticated):


{
    "message": "Unauthenticated."
}
 

Example response (404, Profile Not Found):


{
    "message": "Business profile not found."
}
 

Request      

GET api/business-profile

Headers

Authorization      

Example: Bearer {YOUR_API_TOKEN}

Update the authenticated user's Business Profile.

requires authentication

Allows manual editing and saving of the business profile fields. This endpoint is for direct updates, not for triggering AI re-generation. To re-generate AI content, use the POST /api/business-profile endpoint with relevant inputs.

Example request:
curl --request PUT \
    "https://postfuel.dev/api/business-profile" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"business_name\": \"Acme Solutions Ltd.\",
    \"user_provided_description\": \"We provide cutting-edge solutions...\",
    \"user_provided_urls\": [
        \"vmqeopfuudtdsufvyvddq\"
    ],
    \"ai_generated_business_summary\": \"amniihfqcoynlazghdtqt\",
    \"ai_generated_target_audience_description\": \"qxbajwbpilpmufinllwlo\",
    \"ai_generated_key_products_services_offered\": [
        \"auydlsmsjuryvojcybzvr\"
    ],
    \"ai_generated_unique_selling_propositions_usp\": [
        \"byickznkygloigmkwxphl\"
    ],
    \"ai_generated_brand_voice_and_tone_suggestion\": \"Friendly & Casual\",
    \"ai_generated_core_business_goals_inferred\": [
        \"vazjrcnfbaqywuxhgjjmz\"
    ],
    \"seo_primary_keywords_identified\": [
        \"uxjubqouzswiwxtrkimfc\"
    ],
    \"seo_suggested_long_tail_keywords\": [
        \"atbxspzmrazsroyjpxmqe\"
    ],
    \"seo_content_themes_identified\": [
        \"sedyghenqcopwvownkbam\"
    ],
    \"seo_strengths_observed\": \"lnfngefbeilfzsyuxoezb\",
    \"seo_areas_for_improvement_suggestions\": \"dtabptcyyerevrljcbwkt\"
}"
const url = new URL(
    "https://postfuel.dev/api/business-profile"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "business_name": "Acme Solutions Ltd.",
    "user_provided_description": "We provide cutting-edge solutions...",
    "user_provided_urls": [
        "vmqeopfuudtdsufvyvddq"
    ],
    "ai_generated_business_summary": "amniihfqcoynlazghdtqt",
    "ai_generated_target_audience_description": "qxbajwbpilpmufinllwlo",
    "ai_generated_key_products_services_offered": [
        "auydlsmsjuryvojcybzvr"
    ],
    "ai_generated_unique_selling_propositions_usp": [
        "byickznkygloigmkwxphl"
    ],
    "ai_generated_brand_voice_and_tone_suggestion": "Friendly & Casual",
    "ai_generated_core_business_goals_inferred": [
        "vazjrcnfbaqywuxhgjjmz"
    ],
    "seo_primary_keywords_identified": [
        "uxjubqouzswiwxtrkimfc"
    ],
    "seo_suggested_long_tail_keywords": [
        "atbxspzmrazsroyjpxmqe"
    ],
    "seo_content_themes_identified": [
        "sedyghenqcopwvownkbam"
    ],
    "seo_strengths_observed": "lnfngefbeilfzsyuxoezb",
    "seo_areas_for_improvement_suggestions": "dtabptcyyerevrljcbwkt"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://postfuel.dev/api/business-profile';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'business_name' => 'Acme Solutions Ltd.',
            'user_provided_description' => 'We provide cutting-edge solutions...',
            'user_provided_urls' => [
                'vmqeopfuudtdsufvyvddq',
            ],
            'ai_generated_business_summary' => 'amniihfqcoynlazghdtqt',
            'ai_generated_target_audience_description' => 'qxbajwbpilpmufinllwlo',
            'ai_generated_key_products_services_offered' => [
                'auydlsmsjuryvojcybzvr',
            ],
            'ai_generated_unique_selling_propositions_usp' => [
                'byickznkygloigmkwxphl',
            ],
            'ai_generated_brand_voice_and_tone_suggestion' => 'Friendly & Casual',
            'ai_generated_core_business_goals_inferred' => [
                'vazjrcnfbaqywuxhgjjmz',
            ],
            'seo_primary_keywords_identified' => [
                'uxjubqouzswiwxtrkimfc',
            ],
            'seo_suggested_long_tail_keywords' => [
                'atbxspzmrazsroyjpxmqe',
            ],
            'seo_content_themes_identified' => [
                'sedyghenqcopwvownkbam',
            ],
            'seo_strengths_observed' => 'lnfngefbeilfzsyuxoezb',
            'seo_areas_for_improvement_suggestions' => 'dtabptcyyerevrljcbwkt',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200, Successful Profile Update):


{
    "data": {
        "id": "9c3b4a5e-6d7f-8a9b-0c1d-2e3f4a5b6c7d",
        "user_id": 1,
        "business_name": "Acme Web Solutions",
        "user_provided_description": "Acme Web Solutions builds innovative web applications for startups using Laravel and AI. We focus on delivering scalable and maintainable solutions.",
        "user_provided_urls": [
            "https://acmeweb.example.com",
            "https://acmeweb.example.com/services"
        ],
        "ai_generated_business_summary": "Acme Web Solutions is a development agency specializing in Laravel and AI-driven web applications targeting startup clients, aiming to provide scalable tech solutions.",
        "ai_generated_target_audience_description": "Primarily targets tech startups and entrepreneurs needing custom web application development, particularly those interested in leveraging AI.",
        "ai_generated_key_products_services_offered": [
            "Custom Web Application Development",
            "Laravel Development",
            "AI Integration Services",
            "Startup Technology Consulting"
        ],
        "ai_generated_unique_selling_propositions_usp": [
            "Specialization in Laravel & AI for Startups",
            "Focus on Scalable Solutions",
            "Agile Development Process"
        ],
        "ai_generated_brand_voice_and_tone_suggestion": "Professional & Authoritative",
        "ai_generated_core_business_goals_inferred": [
            "Acquire Startup Clients",
            "Deliver High-Quality Web Apps",
            "Establish Expertise in AI/Laravel Niche"
        ],
        "seo_profile": {
            "primary_keywords_identified": [
                "laravel development",
                "ai web applications",
                "startup web development",
                "custom web apps",
                "scalable solutions"
            ],
            "suggested_long_tail_keywords": [
                "laravel ai integration for startups",
                "custom laravel development agency",
                "scalable web apps for saas startups"
            ],
            "content_themes_identified": [
                "Laravel Framework",
                "AI in Web Development",
                "Startup Technology",
                "Web Application Scalability"
            ],
            "strengths_observed": "Website content clearly outlines specialization in Laravel and AI solutions targeting the startup sector.",
            "areas_for_improvement_suggestions": "Consider creating blog content or case studies focusing on specific AI integrations or successful startup projects."
        },
        "generation_status": "completed",
        "last_generated_at": "2025-05-06T10:00:00.000000Z",
        "error_message": null,
        "created_at": "2025-05-06T09:30:00.000000Z",
        "updated_at": "2025-05-06T10:00:00.000000Z"
    }
}
 

Example response (401, Unauthenticated):


{
    "message": "Unauthenticated."
}
 

Example response (404, Profile Not Found):


{
    "message": "Business profile not found."
}
 

Example response (422, Validation Error):


{
    "message": "The given data was invalid.",
    "errors": {
        "format": [
            "The selected format is invalid."
        ],
        "openai_model": [
            "Invalid OpenAI model specified. Allowed models are: gpt-4.1, gpt-4.1-mini, gpt-4.1-nano."
        ]
    }
}
 

Request      

PUT api/business-profile

Headers

Authorization      

Example: Bearer {YOUR_API_TOKEN}

Content-Type      

Example: application/json

Body Parameters

business_name   string  optional  

The name of your business. Must not be greater than 255 characters. Example: Acme Solutions Ltd.

user_provided_description   string  optional  

A detailed description of your business. Must be at least 50 characters. Must not be greater than 10000 characters. Example: We provide cutting-edge solutions...

user_provided_urls   string[]  optional  

Must be a valid URL. Must not be greater than 2048 characters.

ai_generated_business_summary   string  optional  

Manually edited AI-generated business summary. Must not be greater than 15000 characters. Example: amniihfqcoynlazghdtqt

ai_generated_target_audience_description   string  optional  

Manually edited target audience description. Must not be greater than 10000 characters. Example: qxbajwbpilpmufinllwlo

ai_generated_key_products_services_offered   string[]  optional  

Must not be greater than 500 characters.

ai_generated_unique_selling_propositions_usp   string[]  optional  

Must not be greater than 500 characters.

ai_generated_brand_voice_and_tone_suggestion   string  optional  

Manually set brand voice and tone. Example: Friendly & Casual

Must be one of:
  • Professional & Authoritative
  • Friendly & Casual
  • Witty & Engaging
  • Inspirational & Encouraging
ai_generated_core_business_goals_inferred   string[]  optional  

Must not be greater than 500 characters.

seo_primary_keywords_identified   string[]  optional  

Must not be greater than 100 characters.

seo_suggested_long_tail_keywords   string[]  optional  

Must not be greater than 150 characters.

seo_content_themes_identified   string[]  optional  

Must not be greater than 150 characters.

seo_strengths_observed   string  optional  

Manually edited SEO strengths. Must not be greater than 10000 characters. Example: lnfngefbeilfzsyuxoezb

seo_areas_for_improvement_suggestions   string  optional  

Manually edited SEO improvement suggestions. Must not be greater than 10000 characters. Example: dtabptcyyerevrljcbwkt

Content Strategy Suggestions

Request Generation of Content Strategy Suggestions.

requires authentication

This endpoint queues a job to generate content strategy suggestions based on the authenticated user's active and completed business profile. This action typically consumes credits.

Example request:
curl --request POST \
    "https://postfuel.dev/api/content-strategies" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}"
const url = new URL(
    "https://postfuel.dev/api/content-strategies"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Accept": "application/json",
};

fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://postfuel.dev/api/content-strategies';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_TOKEN}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (202, Request Accepted for Generation):


{
    "message": "Content strategy suggestion request accepted and queued.",
    "suggestion_request_id": "uuid-of-the-suggestion-record"
}
 

Example response (400, Bad Request (e.g., No active business profile)):


{
    "message": "Active and completed business profile required to generate suggestions."
}
 

Example response (401, Unauthenticated):


{
    "message": "Unauthenticated."
}
 

Example response (402, Insufficient Credits):


{
    "error": "Insufficient credits.",
    "message": "This request requires 14 credits, but you only have 10 available."
}
 

Example response (403, Forbidden):


{
    "message": "Subscription Required.",
    "error": "This feature or model requires an active paid subscription."
}
 

Example response (500, Server Error):


{
    "message": "An internal server error occurred.",
    "error": "Failed to process request due to an unexpected issue. Please try again later or contact support if the problem persists."
}
 

Request      

POST api/content-strategies

Headers

Authorization      

Example: Bearer {YOUR_API_TOKEN}

List Content Strategy Suggestions.

requires authentication

Retrieves a paginated list of previously generated content strategy suggestions for the authenticated user.

Example request:
curl --request GET \
    --get "https://postfuel.dev/api/content-strategies?page=1&per_page=15" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}"
const url = new URL(
    "https://postfuel.dev/api/content-strategies"
);

const params = {
    "page": "1",
    "per_page": "15",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://postfuel.dev/api/content-strategies';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_TOKEN}',
        ],
        'query' => [
            'page' => '1',
            'per_page' => '15',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200, Successful retrieval of suggestions):


{
    "data": [
        {
            "id": "a1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d",
            "user_id": 1,
            "business_profile_id": "9c3b4a5e-6d7f-8a9b-0c1d-2e3f4a5b6c7d",
            "suggestions": [
                {
                    "suggested_topic_headline": "Leveraging AI in Laravel: A Guide for Startups",
                    "target_Google Search_query": "AI libraries for Laravel applications",
                    "recommended_generation_preset": "blog_standard",
                    "brief_justification_or_angle": "Targets the core audience (startups) and highlights the unique intersection of AI and Laravel expertise.",
                    "optional_focus_prompt_snippet": "Focus on practical examples and benefits for early-stage companies."
                },
                {
                    "suggested_topic_headline": "Scalability Checklist for Startup Web Applications",
                    "target_Google Search_query": "web application scalability best practices",
                    "recommended_generation_preset": "benefit_listicle",
                    "brief_justification_or_angle": "Addresses a key concern for startups (scalability) and positions Acme as knowledgeable.",
                    "optional_focus_prompt_snippet": "Emphasize how good architecture choices prevent future issues."
                }
            ],
            "generation_status": "completed",
            "error_message": null,
            "created_at": "2025-05-06T11:00:00.000000Z",
            "updated_at": "2025-05-06T11:01:00.000000Z"
        }
    ],
    "links": {
        "first": "http://localhost/api/content-strategies?page=1",
        "last": "http://localhost/api/content-strategies?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "links": [
            {
                "url": null,
                "label": "&laquo; Previous",
                "active": false
            },
            {
                "url": "http://localhost/api/content-strategies?page=1",
                "label": "1",
                "active": true
            },
            {
                "url": null,
                "label": "Next &raquo;",
                "active": false
            }
        ],
        "path": "http://localhost/api/content-strategies",
        "per_page": 15,
        "to": 1,
        "total": 1
    }
}
 

Example response (401, Unauthenticated):


{
    "message": "Unauthenticated."
}
 

Request      

GET api/content-strategies

Headers

Authorization      

Example: Bearer {YOUR_API_TOKEN}

Query Parameters

page   integer  optional  

The page number for pagination. Example: 1

per_page   integer  optional  

Number of items per page. Example: 15

Display a specific Content Strategy Suggestion.

requires authentication

Example request:
curl --request GET \
    --get "https://postfuel.dev/api/content-strategies/&quot;uuid-goes-here&quot;" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}"
const url = new URL(
    "https://postfuel.dev/api/content-strategies/&quot;uuid-goes-here&quot;"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://postfuel.dev/api/content-strategies/"uuid-goes-here"';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_TOKEN}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200, Successful retrieval of a single suggestion):


{
    "data": {
        "id": "0196ab8f-c9a9-7057-a5d0-8ee2c5c67659",
        "user_id": 4,
        "business_profile_id": "0196ab8d-ecfe-7045-b46f-eab611e12730",
        "suggestions": [
            {
                "suggested_topic_headline": "Maximizing ROI with Managed Print Services in the Maritimes",
                "target_Google Search_query": "managed print solutions cost savings maritime canada",
                "recommended_generation_preset": "benefit_listicle",
                "brief_justification_or_angle": "Highlights cost efficiency and productivity gains relevant to the user's business profile and goals.",
                "optional_focus_prompt_snippet": "Focus on tangible savings and workflow improvements for regional businesses."
            },
            {
                "suggested_topic_headline": "Choosing the Right Office Copier: Lease vs Buy for Atlantic Businesses",
                "target_Google Search_query": "printer leasing vs buying nova scotia",
                "recommended_generation_preset": "blog_standard",
                "brief_justification_or_angle": "Addresses a common decision point for the target audience, positioning Xtra as a helpful advisor.",
                "optional_focus_prompt_snippet": "Compare financial implications and service benefits."
            }
        ],
        "generation_status": "completed",
        "error_message": null,
        "created_at": "2025-05-07T16:24:09.000000Z",
        "updated_at": "2025-05-07T16:24:18.000000Z"
    }
}
 

Example response (401, Unauthenticated):


{
    "message": "Unauthenticated."
}
 

Example response (404, Suggestion Not Found):


{
    "message": "Content strategy suggestion not found."
}
 

Request      

GET api/content-strategies/{suggestionId}

Headers

Authorization      

Example: Bearer {YOUR_API_TOKEN}

URL Parameters

suggestionId   string   

The ID of the content strategy suggestion. Example: "uuid-goes-here"