REST API Reference
Read and write SEO metadata for any post on your WordPress site. Automate your workflow with the TamRank REST API.
v1 · REST · JSONBase URL
All API requests are made to your WordPress site's REST API namespace. Replace yoursite.com with your actual domain.
https://yoursite.com/wp-json/tamrank/v1/
Authentication
The TamRank API requires authentication for all requests. Two methods are supported.
Application Passwords (recommended)
WordPress 5.6+ supports Application Passwords natively. Go to Users > Profile > Application Passwords in your WordPress admin to generate one. Use HTTP Basic Auth with your WordPress username and the generated application password.
curl https://yoursite.com/wp-json/tamrank/v1/meta/42 \
-u "admin:XXXX XXXX XXXX XXXX XXXX XXXX"
Cookie + Nonce
If you are making requests from within the WordPress admin (for example, from a custom plugin page), you can authenticate using the built-in cookie and nonce. Pass the nonce as a header or query parameter.
fetch('/wp-json/tamrank/v1/meta/42', {
headers: {
'X-WP-Nonce': wpApiSettings.nonce
}
})
Read SEO Metadata
Free PRORetrieve all SEO metadata for a single post, page, or custom post type. Returns both Free and PRO fields regardless of license. The response always includes every field.
Example Request
curl https://yoursite.com/wp-json/tamrank/v1/meta/42 \
-u "admin:XXXX XXXX XXXX XXXX XXXX XXXX"
Example Response
{
"id": 42,
"meta_title": "How to Improve Core Web Vitals in WordPress",
"meta_description": "Learn practical steps to optimize LCP, FID, and CLS scores on your WordPress site.",
"focus_keyword": "core web vitals wordpress",
"custom_slug": "improve-core-web-vitals-wordpress",
"noindex": false,
"nofollow": false,
"social_title": "Core Web Vitals Guide for WordPress",
"social_description": "Step-by-step guide to passing Core Web Vitals on WordPress.",
"social_image": "https://yoursite.com/wp-content/uploads/cwv-guide-og.jpg",
"canonical_url": "",
"schema_auto_type": "Article",
"schema_auto_extras": [],
"secondary_keywords": [
"page speed optimization",
"wordpress performance"
],
"secondary_keywords_enabled": true
}
Response Fields
| Field | Type | Description |
|---|---|---|
id | integer | The WordPress post ID |
meta_title | string | SEO title shown in search results |
meta_description | string | SEO description shown in search results |
focus_keyword | string | Primary focus keyword for the post |
custom_slug | string | Custom URL slug override |
noindex | boolean | Whether to add a noindex meta tag |
nofollow | boolean | Whether to add a nofollow meta tag |
social_title | string | Open Graph / social media title (PRO) |
social_description | string | Open Graph / social media description (PRO) |
social_image | string | Open Graph image URL (PRO) |
canonical_url | string | Custom canonical URL override (PRO) |
schema_auto_type | string | Auto-detected schema type (PRO) |
schema_auto_extras | array | Additional schema properties (PRO) |
secondary_keywords | array | Up to 5 secondary keywords (PRO) |
secondary_keywords_enabled | boolean | Whether secondary keyword tracking is on (PRO) |
Write SEO Metadata
Free PROCreate or update SEO metadata for a single post. Partial updates are supported: send only the fields you want to change. Omitted fields remain untouched.
Fields
| Field | Type | Max Length | Free | PRO |
|---|---|---|---|---|
meta_title |
string | 120 chars | Write | Write |
meta_description |
string | 320 chars | Write | Write |
focus_keyword |
string | 80 chars | Write | Write |
custom_slug |
string | 200 chars | Write | Write |
noindex |
boolean | - | Write | Write |
nofollow |
boolean | - | Write | Write |
social_title |
string | 120 chars | Read only | Write |
social_description |
string | 320 chars | Read only | Write |
social_image |
URL | 500 chars | Read only | Write |
canonical_url |
URL | 500 chars | Read only | Write |
schema_auto_type |
string | 100 chars | Read only | Write |
schema_auto_extras |
array | - | Read only | Write |
secondary_keywords |
array | max 5 items | Read only | Write |
Free users sending PRO-only fields: The request will still succeed, but PRO-only fields will be silently skipped. The response includes a pro_fields_skipped array showing which fields were ignored.
Example Request
curl -X POST https://yoursite.com/wp-json/tamrank/v1/meta/42 \
-u "admin:XXXX XXXX XXXX XXXX XXXX XXXX" \
-H "Content-Type: application/json" \
-d '{
"meta_title": "How to Improve Core Web Vitals in WordPress",
"meta_description": "A practical guide to optimizing LCP, FID, and CLS.",
"focus_keyword": "core web vitals wordpress",
"noindex": false
}'
Example Response
{
"id": 42,
"updated": true,
"fields_updated": [
"meta_title",
"meta_description",
"focus_keyword",
"noindex"
],
"pro_fields_skipped": []
}
Free User Response (with PRO fields)
When a Free user sends PRO-only fields, those fields are skipped and listed in the response:
{
"id": 42,
"updated": true,
"fields_updated": [
"meta_title",
"focus_keyword"
],
"pro_fields_skipped": [
"social_title",
"canonical_url"
]
}
Batch Update
PROUpdate SEO metadata for multiple posts in a single request. Each item in the array follows the same schema as the single POST endpoint. Results are returned per post, with individual success or error status.
PRO only. Maximum 50 items per request. Rate limited to 5 requests per minute.
Example Request
curl -X POST https://yoursite.com/wp-json/tamrank/v1/meta/batch \
-u "admin:XXXX XXXX XXXX XXXX XXXX XXXX" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"post_id": 42,
"meta_title": "Updated Title for Post 42",
"focus_keyword": "core web vitals"
},
{
"post_id": 87,
"meta_title": "SEO Guide for Beginners",
"meta_description": "Everything you need to know about on-page SEO.",
"noindex": false
},
{
"post_id": 9999,
"meta_title": "This Post Does Not Exist"
}
]
}'
Example Response
The response contains a results array. Each entry shows the outcome for that post. Failures do not block other items from being processed.
{
"results": [
{
"post_id": 42,
"updated": true,
"fields_updated": ["meta_title", "focus_keyword"]
},
{
"post_id": 87,
"updated": true,
"fields_updated": ["meta_title", "meta_description", "noindex"]
},
{
"post_id": 9999,
"error": "rest_post_invalid_id",
"message": "Invalid post ID."
}
],
"total": 3,
"succeeded": 2,
"failed": 1
}
Limits
- Maximum 50 items per batch request
- PRO license required (Free users receive a 403 error)
- Rate limited to 5 requests per minute
Schema Markup
TamRank supports automatic schema detection and manual schema templates. The automatically detected schema fields are available via the API.
Supported Schema Types
| Type | Description |
|---|---|
WebPage | Default web page |
AboutPage | About us page |
ContactPage | Contact page |
CollectionPage | Overview page (category, tag) |
ItemPage | Individual item |
BlogPosting | Blog post / article |
Product | Product page |
FAQPage | Frequently asked questions |
HowTo | Step-by-step guide |
VideoObject | Video page |
ImageObject | Image page |
Event | Event |
Recipe | Recipe |
LocalBusiness | Local business |
NewsArticle | News article |
Extra schema types (can be combined with a main type): FAQPage, VideoObject, HowTo, ImageObject
API Fields
| Field | Type | Description | Free | PRO |
|---|---|---|---|---|
schema_auto_type | string | Main schema type (e.g. "BlogPosting") | Read | Write |
schema_auto_extras | array | Extra schema types (e.g. ["FAQPage"]) | Read | Write |
Auto-detection vs. API
- Auto-detection (PRO): TamRank analyzes your page content and picks the best schema type. Stored in
schema_auto_typeandschema_auto_extras. - Via the API (PRO): You can override
schema_auto_typeandschema_auto_extrasmanually. Useful for bulk updates or when you want full control. - Manual templates: Advanced schema templates with custom field mappings are managed in WordPress admin and are not currently available via the API.
Example: Set schema via API
curl -X POST -u "user:app-password" \
-H "Content-Type: application/json" \
-d '{
"schema_auto_type": "Product",
"schema_auto_extras": ["FAQPage"]
}' \
https://yoursite.com/wp-json/tamrank/v1/meta/42
Rate Limiting
Every API response includes rate limit headers so you can track your usage.
Response Headers
X-RateLimit-Limit- Maximum number of requests allowed in the current window
X-RateLimit-Remaining- Number of requests remaining in the current window
X-RateLimit-Reset- Unix timestamp when the rate limit window resets
Rate Limits by Tier
| Action | Free | PRO |
|---|---|---|
| Read (GET) | 30 / min | 120 / min |
| Write (POST) | 10 / min | 30 / min |
| Batch (POST /batch) | Not available | 5 / min |
429 Response Example
When you exceed the rate limit, the API returns a 429 status code with a Retry-After header indicating how many seconds to wait.
HTTP/1.1 429 Too Many Requests
Retry-After: 34
X-RateLimit-Limit: 30
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1711296000
{
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded. Try again in 34 seconds.",
"data": {
"status": 429
}
}
Error Codes
The API uses standard HTTP status codes. Error responses include a code field for programmatic handling and a human-readable message.
| Status | Code | Description |
|---|---|---|
400 |
rest_invalid_param |
Field exceeds max length or has an invalid format |
400 |
batch_too_large |
More than 50 items in a batch request |
401 |
rest_forbidden |
Not authenticated (missing or invalid credentials) |
403 |
rest_forbidden |
Authenticated but lacking edit_post capability |
403 |
rest_forbidden_pro |
PRO license required for this action |
429 |
rate_limit_exceeded |
Rate limit reached, check Retry-After header |
Error Response Format
{
"code": "rest_invalid_param",
"message": "meta_title exceeds the maximum length of 120 characters.",
"data": {
"status": 400,
"params": {
"meta_title": "Must be 120 characters or fewer."
}
}
}
Validation
All input is validated and sanitized before saving. Here is what to expect.
- Text fields are stripped of HTML tags to prevent injection
- Descriptions preserve line breaks (\n) but strip all HTML
- URLs (social_image, canonical_url) are validated for proper format
- Booleans accept
true/false,1/0, or"yes"/"no" - Field lengths are checked against the maximum before saving (see the fields table above)
- secondary_keywords accepts a maximum of 5 items in the array
If any field fails validation, the entire request is rejected and no fields are saved. The error response will indicate which field(s) failed and why.
Free vs PRO API Access
- Read all SEO fields
- Write 6 core fields (title, description, keyword, slug, noindex, nofollow)
- 30 reads / 10 writes per minute
- Write all 13 fields (including social, schema, canonical)
- Batch endpoint: update 50 posts per request
- 120 reads / 30 writes per minute
Ready to automate your SEO?
The TamRank REST API is included with every installation. Free gives you full read access and core field writes. PRO unlocks batch operations, all writable fields, and higher rate limits.