📚 API Documentation

⚠️ Important Notes:
  • Your shop must be active, and valid subscription
  • All endpoints return JSON responses

🔍 Overview

The Posts API allows you to manage blog posts, articles, and product reviews, orders, ... for your website. Each post can have dynamic data fields for flexible content management.

📋 Base URL

https://your-shop-domain.com

🔑 Authentication Methods

⚠️ Important:
  • All write operations (POST, PUT, PATCH, DELETE) require JWT authentication
  • Read operations (GET) may require authentication depending on shop settings
  • JWT tokens expire after 1 hour, refresh tokens expire after 7 days
  • Always use HTTPS in production for secure token transmission
  • Include JWT token in Authorization header: Authorization: Bearer YOUR_TOKEN

Shop User Authentication

Use these endpoints to authenticate a Shop User scoped to a specific shop (identified from the request host). The issued tokens include shop_user_id, shop_id, and type set to shop_access or shop_refresh.

POST /api/shop_auth/register

Register a new shop user for the current shop and receive JWT tokens.

/api/shop_auth/register
Request Body
  • email (string, required)
  • password (string, required)
  • name (string, optional)
Example Request
curl -X POST "https://your-shop-domain.com/api/shop_auth/register" \ -H "Content-Type: application/json" \ -d '{ "email": "staff@example.com", "password": "secret", "name": "Staff" }'

POST /api/shop_auth/login

Authenticate shop user and receive JWT tokens.

/api/shop_auth/login
Request Body
  • email (string, required)
  • password (string, required)
Example Request
curl -X POST "https://your-shop-domain.com/api/shop_auth/login" \ -H "Content-Type: application/json" \ -d '{ "email": "staff@example.com", "password": "secret" }'
Successful Response
{ "success": true, "message": "Login successful", "data": { "user": { "id": 12, "email": "staff@example.com", "name": "Staff" }, "tokens": { "access_token": "...", "refresh_token": "...", "token_type": "Bearer", "expires_in": 3600 } } }

POST /api/shop_auth/refresh

Refresh expired access token using a valid shop refresh token.

/api/shop_auth/refresh
Request Body
  • refresh_token (string, required)
Example Request
curl -X POST "https://your-shop-domain.com/api/shop_auth/refresh" \ -H "Content-Type: application/json" \ -d '{ "refresh_token": "YOUR_REFRESH_TOKEN" }'

POST /api/shop_auth/logout

Logout and blacklist current shop access token.

/api/shop_auth/logout
Headers
  • Authorization: Bearer YOUR_ACCESS_TOKEN
Example Request
curl -X POST "https://your-shop-domain.com/api/shop_auth/logout" \ -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9..." \ -H "Content-Type: application/json"

GET /api/shop_auth/me

Get current authenticated shop user info.

/api/shop_auth/me
Headers
  • Authorization: Bearer YOUR_ACCESS_TOKEN
Example Request
curl -X GET "https://your-shop-domain.com/api/shop_auth/me" \ -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9..." \ -H "Content-Type: application/json"

🔑 API Key Authentication

For server-to-server integrations, you can use API keys instead of JWT tokens.

Using API Key

curl -X POST "https://your-shop-domain.com/posts" \ -H "X-API-Key: your_api_key_here" \ -H "Content-Type: application/json" \ -d '{ "post": { "title": "API Key Post", "content": "Created using API key authentication" } }'

🔑 Session Authentication

For web applications, you can also use session-based authentication.

Using Session Cookie

curl -X POST "https://your-shop-domain.com/posts" \ -H "Cookie: _session_id=your_session_cookie" \ -H "Content-Type: application/json" \ -d '{ "post": { "title": "Session Post", "content": "Created using session authentication" } }'

🔑 Using JWT Tokens with Posts API

Complete Workflow with JWT Authentication

# 1. Login to get Shop User JWT tokens curl -X POST "https://your-shop-domain.com/api/shop_auth/login" \ -H "Content-Type: application/json" \ -d '{ "email": "staff@example.com", "password": "secret" }' # Response will contain access_token and refresh_token # Store these tokens securely # 2. Create post using JWT token curl -X POST "https://your-shop-domain.com/posts" \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "post": { "title": "My First Post", "content": "This is my first post using JWT authentication", "active": true, "post_type": "article" } }' # 3. Update post using JWT token curl -X PUT "https://your-shop-domain.com/posts/1" \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "post": { "title": "Updated Post Title", "active": false } }' # 4. Refresh token when it expires curl -X POST "https://your-shop-domain.com/api/shop_auth/refresh" \ -H "Content-Type: application/json" \ -d '{ "refresh_token": "YOUR_REFRESH_TOKEN" }' # 5. Logout when done curl -X POST "https://your-shop-domain.com/api/shop_auth/logout" \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json"

🚀 API Endpoints

GET /posts

Retrieve a list of posts with optional filtering and pagination.

/posts

Query Parameters

ParameterTypeRequiredDescription
querystringNoSearch term to filter posts
category_idintegerNoFilter posts by category ID
activebooleanNoFilter by active status
post_typestringNoFilter by post type
pageintegerNoPage number (default: 1)
per_pageintegerNoItems per page (default: 20, max: 50)

Example Request

curl -X GET "https://your-shop-domain.com/posts?query=iPhone&category_id=1&page=1&per_page=10" \ -H "Content-Type: application/json"

Success Response

{ "success": true, "data": { "posts": [ { "id": 1, "title": "iPhone 15 Pro Review", "content": "Detailed review...", "active": true, "post_type": "review", "category_id": 1, "body_data": {"product_name": "iPhone 15 Pro", "price": "999"}, "slug": "iphone-15-pro-review", "created_at": "2023-10-15T10:30:00Z", "updated_at": "2023-10-15T10:30:00Z" } ], "pagination": { "total_pages": 5, "current_page": 1, "per_page": 10, "total_count": 48 } } }

GET /posts/:id

Retrieve a specific post by ID or slug.

/posts/{id_or_slug}

Example Request

curl -X GET "https://your-shop-domain.com/posts/1" \ -H "Content-Type: application/json"

Success Response

{ "success": true, "data": { "post": { "id": 1, "title": "iPhone 15 Pro Review", "content": "Detailed review...", "active": true, "post_type": "review", "category_id": 1, "body_data": {"product_name": "iPhone 15 Pro", "price": "999"}, "slug": "iphone-15-pro-review", "created_at": "2023-10-15T10:30:00Z", "updated_at": "2023-10-15T10:30:00Z" } } }

POST /posts

Create a new post.

/posts

Request Body

FieldTypeRequiredDescription
post[title]stringYesPost title
post[content]textNoPost content
post[active]booleanNoActive status
post[post_type]stringNoPost type
post[category_id]integerNoCategory ID
post[image_link]stringNoImage URL
post[body_data]objectNoDynamic data fields

Example Request

curl -X POST "https://your-shop-domain.com/posts" \ -H "Authorization: Bearer YOUR_JWT_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "post": { "title": "iPhone 15 Pro Max Review", "content": "Comprehensive review...", "active": true, "post_type": "product_review", "category_id": 1, "image_link": "https://example.com/iphone.jpg", "body_data": { "brand": "Apple", "model": "iPhone 15 Pro Max", "price_usd": "1199", "rating": "4.8", "colors": "Natural Titanium, Blue Titanium" } } }'

Success Response (201 Created)

{ "success": true, "message": "Post created successfully", "data": { "post": { "id": 2, "title": "iPhone 15 Pro Max Review", "slug": "iphone-15-pro-max-review", "created_at": "2023-10-15T11:00:00Z", "updated_at": "2023-10-15T11:00:00Z" } } }

PUT/PATCH /posts/:id

Update an existing post.

/posts/{id_or_slug}

Example Request

curl -X PUT "https://your-shop-domain.com/posts/1" \ -H "Authorization: Bearer YOUR_JWT_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "post": { "title": "Updated iPhone 15 Pro Review", "active": true, "body_data": { "price": "899", "discount": "10%" } } }'

Success Response

{ "success": true, "message": "Post updated successfully", "data": { "post": { "id": 1, "title": "Updated iPhone 15 Pro Review", "updated_at": "2023-10-15T12:00:00Z" } } }

DELETE /posts/:id

Delete a post.

/posts/{id_or_slug}

Example Request

curl -X DELETE "https://your-shop-domain.com/posts/1" \ -H "Authorization: Bearer YOUR_JWT_TOKEN" \ -H "Content-Type: application/json"

Success Response

{ "success": true, "message": "Post deleted successfully" }

GET /posts/search

Advanced search functionality for posts.

/posts/search

Query Parameters

ParameterTypeRequiredDescription
qstringNoSearch query
category_idintegerNoFilter by category
activebooleanNoFilter by status
post_typestringNoFilter by type
body_data_keystringNoSearch by body_data key
body_data_valuestringNoSearch by body_data value
pageintegerNoPage number
per_pageintegerNoItems per page

Example Request

curl -X GET "https://your-shop-domain.com/posts/search?body_data_key=brand&body_data_value=Apple&page=1&per_page=20" \ -H "Content-Type: application/json"

GET /posts/:id/body_data

Retrieve only the dynamic data of a specific post.

/posts/{id_or_slug}/body_data

Example Request

curl -X GET "https://your-shop-domain.com/posts/1/body_data" \ -H "Content-Type: application/json"

Success Response

{ "success": true, "data": { "body_data": { "brand": "Apple", "model": "iPhone 15 Pro Max", "price_usd": "1199", "rating": "4.8" }, "dynamic_variables_count": 4, "available_keys": ["brand", "model", "price_usd", "rating"] } }

PATCH /posts/:id/update_body_data

Update only the dynamic data of a specific post.

/posts/{id_or_slug}/update_body_data

Example Request

curl -X PATCH "https://your-shop-domain.com/posts/1/update_body_data" \ -H "Authorization: Bearer YOUR_JWT_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "post": { "body_data": { "price": "899", "discount": "25%", "sale_end_date": "2023-12-31", "stock_quantity": "50" } } }'

Success Response

{ "success": true, "message": "Body data updated successfully", "data": { "body_data": { "price": "899", "discount": "25%", "sale_end_date": "2023-12-31", "stock_quantity": "50" }, "dynamic_variables_count": 4 } }

🔧 Body Data Validation Rules

⚠️ Important Validation Rules for body_data:

  • Maximum keys: 50 keys per post
  • Key format: Only letters, numbers, underscore (_), and hyphen (-)
  • Key length: Maximum 100 characters
  • Value length: Maximum 1,000 characters for strings
  • Total size: Maximum 100KB for entire body_data object
  • Reserved keys: Cannot use: title, content, slug, post_type, category_id
  • Forbidden content: No script tags, javascript: protocol, or data: URIs
  • Value types: Only strings, numbers, booleans, and null values

🚨 Error Responses

Common Error Codes

Status CodeError TypeDescription
400Bad RequestInvalid request parameters
403ForbiddenShop validation failed
404Not FoundPost not found
422Unprocessable EntityValidation errors
500Internal Server ErrorServer error

Example Error Responses

Shop Validation Error (403):
{ "success": false, "error": "Shop is not active" }
Validation Error (422):
{ "success": false, "error": "Failed to create post", "validation_errors": [ "Title can't be blank", "Body data key 'invalid@key' contains invalid characters" ] }

📝 Complete Workflow Example

Create, Update, and Delete a Post

# 1. Create a new post curl -X POST "https://your-shop-domain.com/posts" \ -H "Content-Type: application/json" \ -d '{ "post": { "title": "Test Product Review", "content": "This is a test review", "active": true, "post_type": "review", "category_id": 1, "body_data": { "product_name": "Test Product", "price": "99.99", "rating": "4.5" } } }' # 2. Get the created post curl -X GET "https://your-shop-domain.com/posts/1" \ -H "Content-Type: application/json" # 3. Update the post curl -X PUT "https://your-shop-domain.com/posts/1" \ -H "Content-Type: application/json" \ -d '{ "post": { "title": "Updated Test Product Review", "body_data": { "price": "89.99", "discount": "10%" } } }' # 4. Search for the post curl -X GET "https://your-shop-domain.com/posts/search?q=Test&active=true" \ -H "Content-Type: application/json" # 5. Delete the post curl -X DELETE "https://your-shop-domain.com/posts/1" \ -H "Content-Type: application/json"

🔗 Additional Resources

  • Rate Limiting: No specific rate limits, but be reasonable
  • Pagination: Always use pagination for large datasets
  • Search: Use the search endpoint for complex queries
  • Body Data: Use for flexible, dynamic content storage
  • Slugs: Automatically generated from titles

⚠️ Production Considerations

  • Always include proper error handling
  • Use HTTPS in production environments
  • Implement proper caching strategies
  • Monitor API usage and performance
  • Keep body_data size reasonable

🌐 Landing Pages API

The Landing Pages API allows you to manage static and dynamic landing pages for your shop.

GET /lp

List (Search) Landing Pages

/lp.json

Query Parameters

ParameterTypeRequiredDescription
querystringNoSearch query
pageintegerNoPage number for pagination (default: 1)
per_pageintegerNoNumber of items per page (default: 20)
category_idintegerNoFilter by category ID
idsstringNoComma-separated list of specific page IDs (e.g., "1,2,3,4")

Example Request

curl -X GET "https://your-shop-domain.com/lp.json?query=marketing&page=1&per_page=10&category_id=5" \ -H "Content-Type: application/json"

Success Response

{ "data": [ { "id": 1, "name": "Marketing Landing Page", "slug": "marketing-landing-page", "page_type": "static", "keyword": "marketing", "intro": "Professional marketing landing page", "category_id": 5, "active": true, "copy_from_id": null, "created_at": "2024-01-15T10:30:00Z", "updated_at": "2024-01-15T10:30:00Z" } ], "pagination": { "total_pages": 10, "current_page": 1, "per_page": 20, "total_count": 200 } }
Note: This endpoint uses Searchkick for full-text search. The query parameter supports advanced search syntax.

GET /lp/:id

Detail Landing Page

/lp/{id}.json

Parameters

ParameterTypeRequiredDescription
idintegerYesLanding page ID or slug (friendly find)

Example Request

curl -X GET "https://your-shop-domain.com/lp/1.json" \ -H "Content-Type: application/json"

Success Response

{ "data": { "id": 1, "name": "Marketing Landing Page", "slug": "marketing-landing-page", "page_type": "static", "keyword": "marketing", "intro": "Professional marketing landing page with call-to-action", "content": "<html><body><h1>Welcome to our marketing page</h1>...</body></html>", "category_id": 5, "active": true, "copy_from_id": null, "body_data": { "custom_field_1": "value1", "custom_field_2": "value2" }, "created_at": "2024-01-15T10:30:00Z", "updated_at": "2024-01-15T10:30:00Z" } }
Note: The body_data field contains dynamic variables specific to the landing page. This field is excluded from the list endpoint for performance.

💬 Feedback API

The Feedback API allows you to submit feedback and reviews for your shop.

POST /feedbacks

Create Feedback

/feedbacks.json

Parameters

ParameterTypeRequiredDescription
feedback[name]stringYesName of the person providing feedback
feedback[email]stringYesEmail address of the person
feedback[content]stringYesFeedback message content. Can be plain text or JSON object for structured data

Example Request

curl -X POST "https://your-shop-domain.com/feedbacks.json" \ -H "Content-Type: application/json" \ -H "X-CSRF-Token: [your_csrf_token]" \ -d '{ "feedback": { "name": "John Doe", "email": "john@example.com", "content": "Great website! Very user-friendly interface." } }'

Example Request with Structured JSON Content

curl -X POST "https://your-shop-domain.com/feedbacks.json" \ -H "Content-Type: application/json" \ -H "X-CSRF-Token: [your_csrf_token]" \ -d '{ "feedback": { "name": "John Doe", "email": "john@example.com", "content": "{\"rating\": \"5\", \"category\": \"UI/UX\", \"suggestion\": \"Add dark mode\"}" } }'

Success Response

{ "data": { "id": 1, "name": "John Doe", "email": "john@example.com", "content": "Great website! Very user-friendly interface.", "shop_id": 5, "created_at": "2024-01-15T10:30:00Z", "updated_at": "2024-01-15T10:30:00Z" } }

Success Response (with JSON content)

{ "data": { "id": 1, "name": "John Doe", "email": "john@example.com", "content": "{\"rating\": \"5\", \"category\": \"UI/UX\", \"suggestion\": \"Add dark mode\"}", "shop_id": 5, "created_at": "2024-01-15T10:30:00Z", "updated_at": "2024-01-15T10:30:00Z" } }

Rate Limit Exceeded Response

{ "msg": "error req" }
Content Field: The content field accepts both plain text and JSON strings. When JSON is provided, it will be parsed and displayed as a structured table in the admin interface.
Stored: See your feedbacks/subscribe/post ... in admin dashboard.

🚨 Error Responses

Common Error Codes

Status CodeDescriptionExample
404Landing page not found{"error": "Landing page not found"}
422Validation error{"errors": {"title": ["can't be blank"]}}
422Rate limit exceeded{"msg": "error req"}
500Internal server error{"error": "Internal server error"}