Error Codes

Complete reference of API error responses

Error Codes

All error responses follow a consistent format:

{
  "error": "ERROR_CODE",
  "message": "Human-readable error message",
  ...additional fields
}

Authentication Errors

MISSING_API_KEY

Status Code: 401 Unauthorized

{
  "error": "MISSING_API_KEY",
  "message": "API key is required in x-api-key header"
}

Cause: No x-api-key header provided

Solution: Include your API key in the header:

curl https://api.postcore.dev/profiles \
  -H "x-api-key: YOUR_API_KEY"

INVALID_API_KEY

Status Code: 401 Unauthorized

{
  "error": "INVALID_API_KEY",
  "message": "Invalid API key"
}

Causes:

  • API key doesn't exist
  • API key was deleted
  • Typo in the key

Solution: Verify your API key in the dashboard

Profile Errors

PROFILE_NOT_FOUND

Status Code: 404 Not Found

{
  "error": "PROFILE_NOT_FOUND",
  "message": "Profile not found"
}

Causes:

  • Invalid profile ID
  • Profile was deleted
  • Profile belongs to different account

PROFILE_ALREADY_EXISTS

Status Code: 400 Bad Request

{
  "error": "PROFILE_ALREADY_EXISTS",
  "message": "Profile for this platform already exists"
}

Cause: You already have a profile connected for this platform

Solution: Delete the existing profile first if you want to connect a different account

INVALID_CREDENTIALS

Status Code: 400 Bad Request

{
  "error": "INVALID_CREDENTIALS",
  "message": "Invalid Bluesky credentials"
}

Causes:

  • Wrong handle or app password
  • App password was revoked
  • Typo in credentials

Solution: Verify your Bluesky handle and create a new app password

PLATFORMS_NOT_CONNECTED

Status Code: 400 Bad Request

{
  "error": "PLATFORMS_NOT_CONNECTED",
  "message": "The following platforms are not connected: linkedin",
  "missing_platforms": ["linkedin"]
}

Cause: Trying to post to platforms you haven't connected

Solution: Connect the missing platforms first

Post Errors

POST_NOT_FOUND

Status Code: 404 Not Found

{
  "error": "POST_NOT_FOUND",
  "message": "Post not found"
}

Causes:

  • Invalid post ID
  • Post was deleted
  • Post belongs to different account

POST_PUBLISHED

Status Code: 400 Bad Request

{
  "error": "POST_PUBLISHED",
  "message": "Cannot delete published posts"
}

Cause: Trying to delete a post that has already been published

Solution: Delete the post directly on LinkedIn or Bluesky

CONTENT_TOO_LONG

Status Code: 400 Bad Request

{
  "error": "CONTENT_TOO_LONG",
  "message": "Content exceeds maximum length of 3000 characters",
  "max_length": 3000,
  "provided_length": 3247
}

Cause: Post content exceeds 3000 characters

Solution: Shorten your content

INVALID_SCHEDULED_TIME

Status Code: 400 Bad Request

{
  "error": "INVALID_SCHEDULED_TIME",
  "message": "Scheduled time must be in the future"
}

Causes:

  • Time is in the past
  • Time is less than 1 minute from now
  • Invalid ISO 8601 format

Solution: Schedule at least 1 minute in the future using UTC time

INVALID_PLATFORMS

Status Code: 400 Bad Request

{
  "error": "INVALID_PLATFORMS",
  "message": "Invalid platforms specified",
  "valid_platforms": ["linkedin", "bluesky"]
}

Cause: Provided platform name that doesn't exist

Solution: Use linkedin or bluesky

Rate Limit Errors

RATE_LIMIT_EXCEEDED (API)

Status Code: 429 Too Many Requests

{
  "error": "RATE_LIMIT_EXCEEDED",
  "message": "Rate limit exceeded. Try again in 243 seconds",
  "retry_after": 243
}

Cause: Too many API requests in the time window

Solution: Wait retry_after seconds before making another request

RATE_LIMIT_EXCEEDED (Platform)

Status Code: 429 Too Many Requests

{
  "error": "RATE_LIMIT_EXCEEDED",
  "message": "LinkedIn requires 60 seconds between posts. Next available: 2025-01-15T14:01:00Z",
  "platform": "linkedin",
  "next_available": "2025-01-15T14:01:00Z"
}

Cause: Posts scheduled too close together for the platform

Solution: Use the next_available time for your next post

MONTHLY_LIMIT_EXCEEDED

Status Code: 429 Too Many Requests

{
  "error": "MONTHLY_LIMIT_EXCEEDED",
  "message": "Monthly limit of 10 posts reached",
  "limit": 10,
  "used": 10,
  "resets_at": "2025-02-01T00:00:00Z"
}

Cause: Reached your monthly post creation limit

Solutions:

  • Wait until resets_at (next month)
  • Upgrade to Pro for 3000 posts/month

Validation Errors

INVALID_ID

Status Code: 400 Bad Request

{
  "error": "INVALID_ID",
  "message": "Invalid post ID format"
}

Cause: ID is not a valid UUID

Solution: Use a valid UUID from the API responses

MISSING_REQUIRED_FIELD

Status Code: 400 Bad Request

{
  "error": "MISSING_REQUIRED_FIELD",
  "message": "Missing required field: content",
  "field": "content"
}

Cause: Required field not provided in request body

Solution: Include all required fields

INVALID_JSON

Status Code: 400 Bad Request

{
  "error": "INVALID_JSON",
  "message": "Invalid JSON in request body"
}

Cause: Malformed JSON

Solution: Verify your JSON syntax:

# Bad
curl -d '{"content": "test}' # Missing closing quote

# Good
curl -d '{"content": "test"}'

Server Errors

INTERNAL_SERVER_ERROR

Status Code: 500 Internal Server Error

{
  "error": "INTERNAL_SERVER_ERROR",
  "message": "An unexpected error occurred"
}

Cause: Something went wrong on our end

Solution:

  • Retry the request
  • If it persists, contact support with the request details

SERVICE_UNAVAILABLE

Status Code: 503 Service Unavailable

{
  "error": "SERVICE_UNAVAILABLE",
  "message": "Service temporarily unavailable"
}

Cause: Platform service is down (LinkedIn or Bluesky API issues)

Solution: Wait and retry later

OAuth Errors

OAUTH_ERROR

Status Code: 400 Bad Request

{
  "error": "OAUTH_ERROR",
  "message": "OAuth authorization failed",
  "details": "User denied authorization"
}

Causes:

  • User clicked "Deny" during OAuth
  • OAuth state mismatch
  • Expired authorization code

Solution: Restart the OAuth flow from the beginning

Error Handling Best Practices

Check Status Codes

const response = await fetch("https://api.postcore.dev/posts", {
  method: "POST",
  headers: {
    "x-api-key": apiKey,
    "Content-Type": "application/json",
  },
  body: JSON.stringify(postData),
});

if (!response.ok) {
  const error = await response.json();
  console.error("Error:", error.error);
  console.error("Message:", error.message);

  // Handle specific errors
  if (error.error === "MONTHLY_LIMIT_EXCEEDED") {
    alert("Monthly limit reached. Upgrade to Pro for more posts!");
  } else if (error.error === "RATE_LIMIT_EXCEEDED") {
    setTimeout(() => retryRequest(), error.retry_after * 1000);
  }
}

Retry Logic

async function makeRequest(url, options, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch(url, options);

      if (response.status === 429) {
        // Rate limit
        const error = await response.json();
        await new Promise((resolve) =>
          setTimeout(resolve, error.retry_after * 1000)
        );
        continue; // Retry
      }

      if (response.status >= 500) {
        // Server error
        if (i < maxRetries - 1) {
          await new Promise((resolve) => setTimeout(resolve, 1000 * (i + 1)));
          continue; // Retry with backoff
        }
      }

      return response;
    } catch (err) {
      if (i === maxRetries - 1) throw err;
    }
  }
}

Display User-Friendly Messages

const ERROR_MESSAGES = {
  MONTHLY_LIMIT_EXCEEDED:
    "You've reached your monthly post limit. Upgrade to Pro for more!",
  PLATFORMS_NOT_CONNECTED: "Please connect your social accounts first.",
  RATE_LIMIT_EXCEEDED: "Slow down! You're making requests too quickly.",
  INVALID_CREDENTIALS: "Invalid login credentials. Please check and try again.",
};

function getUserMessage(errorCode) {
  return ERROR_MESSAGES[errorCode] || "Something went wrong. Please try again.";
}