Files
MokoSuiteOpenGraph/openapi.yaml
T
Jonathan Miller e7b0af1fca docs: add OpenAPI 3.0 spec for REST API
Documents the /api/v1/mokoog/tags endpoints with full request/response
schemas, authentication, and examples. Closes #80
2026-06-23 12:53:59 -05:00

669 lines
20 KiB
YAML

openapi: 3.0.3
info:
title: MokoSuiteOpenGraph API
version: 1.0.0
description: |
REST API for managing Open Graph, SEO meta, and structured-data tags in
Joomla via the MokoSuiteOpenGraph extension.
The API follows Joomla's Web Services conventions and returns responses in
[JSON:API](https://jsonapi.org/) format. All endpoints require
authentication via a Joomla API token.
contact:
name: Moko Consulting
email: hello@mokoconsulting.tech
license:
name: GPL-3.0-or-later
url: https://www.gnu.org/licenses/gpl-3.0.html
servers:
- url: /api/index.php/v1
description: Joomla Web Services API
security:
- apiToken: []
tags:
- name: Tags
description: CRUD operations for Open Graph tag records
paths:
/mokoog/tags:
get:
operationId: listTags
summary: List OG tags
description: |
Returns a paginated collection of OG tag records. Supports filtering
by content type, published state, and language.
tags: [Tags]
parameters:
- name: "filter[content_type]"
in: query
description: Filter by content type (e.g. `com_content`, `menu`, `com_mokoshop`)
schema:
type: string
example: com_content
- name: "filter[content_id]"
in: query
description: Filter by content ID
schema:
type: integer
example: 42
- name: "filter[published]"
in: query
description: Filter by published state
schema:
type: integer
enum: [0, 1]
- name: "filter[language]"
in: query
description: Filter by language tag (e.g. `en-GB`, `*`)
schema:
type: string
example: "*"
- name: "filter[search]"
in: query
description: Free-text search across tag fields
schema:
type: string
- name: "page[offset]"
in: query
description: Number of records to skip (pagination offset)
schema:
type: integer
minimum: 0
default: 0
- name: "page[limit]"
in: query
description: Maximum number of records to return
schema:
type: integer
minimum: 1
maximum: 100
default: 25
- name: "list[fullordering]"
in: query
description: Sort order for results
schema:
type: string
enum:
- a.id ASC
- a.id DESC
- a.og_title ASC
- a.og_title DESC
- a.modified ASC
- a.modified DESC
default: a.modified DESC
responses:
"200":
description: A JSON:API collection of OG tags
content:
application/vnd.api+json:
schema:
$ref: "#/components/schemas/TagCollection"
example:
links:
self: "/api/index.php/v1/mokoog/tags"
data:
- type: tags
id: "1"
attributes:
content_type: com_content
content_id: 42
og_title: "My Article Title"
og_description: "A brief description for social sharing."
og_image: "images/mokoog/og-banner.jpg"
og_type: article
seo_title: "My Article | Example Site"
meta_description: "A brief meta description for search engines."
robots: "index, follow"
canonical_url: "https://example.com/my-article"
language: "*"
published: 1
created: "2026-06-01T12:00:00+00:00"
modified: "2026-06-15T08:30:00+00:00"
meta:
total-pages: 1
"401":
$ref: "#/components/responses/Unauthorized"
post:
operationId: createTag
summary: Create an OG tag
description: |
Creates a new OG tag record. The combination of `content_type`,
`content_id`, and `language` must be unique.
tags: [Tags]
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/TagCreateRequest"
example:
content_type: com_content
content_id: 42
og_title: "My Article Title"
og_description: "A brief description for social sharing."
og_image: "images/mokoog/og-banner.jpg"
og_type: article
language: "*"
published: 1
responses:
"200":
description: The created tag
content:
application/vnd.api+json:
schema:
$ref: "#/components/schemas/TagDocument"
example:
links:
self: "/api/index.php/v1/mokoog/tags/1"
data:
type: tags
id: "1"
attributes:
content_type: com_content
content_id: 42
og_title: "My Article Title"
og_description: "A brief description for social sharing."
og_image: "images/mokoog/og-banner.jpg"
og_type: article
seo_title: ""
meta_description: ""
robots: ""
canonical_url: ""
language: "*"
published: 1
created: "2026-06-23T10:00:00+00:00"
modified: "2026-06-23T10:00:00+00:00"
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
/mokoog/tags/{id}:
parameters:
- $ref: "#/components/parameters/TagId"
get:
operationId: getTag
summary: Get a single OG tag
tags: [Tags]
responses:
"200":
description: A single OG tag resource
content:
application/vnd.api+json:
schema:
$ref: "#/components/schemas/TagDocument"
example:
links:
self: "/api/index.php/v1/mokoog/tags/1"
data:
type: tags
id: "1"
attributes:
content_type: com_content
content_id: 42
og_title: "My Article Title"
og_description: "A brief description for social sharing."
og_image: "images/mokoog/og-banner.jpg"
og_type: article
seo_title: "My Article | Example Site"
meta_description: "A brief meta description for search engines."
robots: "index, follow"
canonical_url: "https://example.com/my-article"
language: "*"
published: 1
created: "2026-06-01T12:00:00+00:00"
modified: "2026-06-15T08:30:00+00:00"
"401":
$ref: "#/components/responses/Unauthorized"
"404":
$ref: "#/components/responses/NotFound"
patch:
operationId: updateTag
summary: Update an OG tag
description: Partially updates an existing OG tag. Only supplied fields are changed.
tags: [Tags]
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/TagUpdateRequest"
example:
og_title: "Updated Title"
og_description: "Updated social description."
published: 0
responses:
"200":
description: The updated tag
content:
application/vnd.api+json:
schema:
$ref: "#/components/schemas/TagDocument"
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
"404":
$ref: "#/components/responses/NotFound"
delete:
operationId: deleteTag
summary: Delete an OG tag
tags: [Tags]
responses:
"204":
description: Tag deleted successfully
"401":
$ref: "#/components/responses/Unauthorized"
"404":
$ref: "#/components/responses/NotFound"
/mokoog/lookup/{content_type}/{content_id}:
get:
operationId: lookupTag
summary: Look up an OG tag by content type and content ID
description: |
Resolves an OG tag by its `content_type` and `content_id` pair and
returns the full tag resource. This is a convenience endpoint that
avoids the caller needing to know the internal tag ID.
tags: [Tags]
parameters:
- name: content_type
in: path
required: true
description: |
The content type identifier (e.g. `com_content`, `menu`,
`com_mokoshop`). Must match the pattern `[a-z][a-z0-9_.]*`.
schema:
type: string
pattern: "^[a-z][a-z0-9_.]*$"
example: com_content
- name: content_id
in: path
required: true
description: The content item ID
schema:
type: integer
minimum: 1
example: 42
responses:
"200":
description: The matching OG tag resource
content:
application/vnd.api+json:
schema:
$ref: "#/components/schemas/TagDocument"
"400":
description: Missing or invalid content_type / content_id
content:
application/vnd.api+json:
schema:
$ref: "#/components/schemas/ErrorResponse"
example:
errors:
- title: Bad Request
status: 400
detail: "content_type and content_id are required"
"401":
$ref: "#/components/responses/Unauthorized"
"404":
description: No OG tag found for the given content_type and content_id
content:
application/vnd.api+json:
schema:
$ref: "#/components/schemas/ErrorResponse"
example:
errors:
- title: Not Found
status: 404
detail: "OG tag not found for com_content:42"
components:
securitySchemes:
apiToken:
type: apiKey
name: X-Joomla-Token
in: header
description: |
Joomla API token. Can also be passed as the `api-token` query
parameter. Generate a token from the Joomla administrator panel
under Users > Manage > [user] > Joomla API Token tab.
parameters:
TagId:
name: id
in: path
required: true
description: The OG tag record ID
schema:
type: integer
minimum: 1
example: 1
schemas:
TagAttributes:
type: object
description: Full set of OG tag attributes returned by the API
properties:
content_type:
type: string
description: |
Content type identifier (e.g. `com_content`, `menu`,
`com_mokoshop`). Must match `[a-z][a-z0-9_.]*`.
pattern: "^[a-z][a-z0-9_.]*$"
maxLength: 100
example: com_content
content_id:
type: integer
description: The ID of the associated content item
minimum: 1
example: 42
og_title:
type: string
description: Open Graph title (`og:title`)
maxLength: 255
example: "My Article Title"
og_description:
type: string
description: Open Graph description (`og:description`)
example: "A brief description for social sharing."
og_image:
type: string
description: Relative path to the Open Graph image (`og:image`)
maxLength: 512
example: "images/mokoog/og-banner.jpg"
og_type:
type: string
description: Open Graph type (`og:type`)
default: article
enum:
- article
- website
- product
- profile
- book
- music.song
- music.album
- video.movie
- video.episode
- video.other
example: article
seo_title:
type: string
description: SEO page title (used in `<title>` tag)
maxLength: 70
example: "My Article | Example Site"
meta_description:
type: string
description: Meta description for search engines
maxLength: 200
example: "A brief meta description for search engines."
robots:
type: string
description: |
Comma-separated robots directives. Valid directives: `index`,
`noindex`, `follow`, `nofollow`, `none`, `noarchive`,
`nosnippet`, `noimageindex`, `max-snippet`, `max-image-preview`.
maxLength: 100
example: "index, follow"
canonical_url:
type: string
format: uri
description: Canonical URL for the page
maxLength: 512
example: "https://example.com/my-article"
language:
type: string
description: Joomla language tag (`*` for all languages)
maxLength: 7
default: "*"
example: "*"
published:
type: integer
description: Published state (1 = published, 0 = unpublished)
enum: [0, 1]
default: 1
example: 1
created:
type: string
format: date-time
description: Record creation timestamp (read-only)
readOnly: true
example: "2026-06-01T12:00:00+00:00"
modified:
type: string
format: date-time
description: Last modification timestamp (read-only)
readOnly: true
example: "2026-06-15T08:30:00+00:00"
TagResource:
type: object
description: A single OG tag in JSON:API resource format
required: [type, id, attributes]
properties:
type:
type: string
enum: [tags]
example: tags
id:
type: string
description: The record ID as a string (per JSON:API spec)
example: "1"
attributes:
$ref: "#/components/schemas/TagAttributes"
TagDocument:
type: object
description: JSON:API document containing a single tag resource
properties:
links:
type: object
properties:
self:
type: string
example: "/api/index.php/v1/mokoog/tags/1"
data:
$ref: "#/components/schemas/TagResource"
TagCollection:
type: object
description: JSON:API document containing a collection of tag resources
properties:
links:
type: object
properties:
self:
type: string
example: "/api/index.php/v1/mokoog/tags"
data:
type: array
items:
$ref: "#/components/schemas/TagResource"
meta:
type: object
properties:
total-pages:
type: integer
description: Total number of pages available
example: 1
TagCreateRequest:
type: object
description: Request body for creating a new OG tag
required:
- content_type
- content_id
properties:
content_type:
type: string
pattern: "^[a-z][a-z0-9_.]*$"
maxLength: 100
example: com_content
content_id:
type: integer
minimum: 1
example: 42
og_title:
type: string
maxLength: 255
og_description:
type: string
og_image:
type: string
maxLength: 512
og_type:
type: string
default: article
enum:
- article
- website
- product
- profile
- book
- music.song
- music.album
- video.movie
- video.episode
- video.other
og_video:
type: string
format: uri
description: Open Graph video URL (`og:video`)
maxLength: 512
seo_title:
type: string
maxLength: 70
meta_description:
type: string
maxLength: 200
robots:
type: string
maxLength: 100
canonical_url:
type: string
format: uri
maxLength: 512
language:
type: string
maxLength: 7
default: "*"
published:
type: integer
enum: [0, 1]
default: 1
TagUpdateRequest:
type: object
description: |
Request body for updating an OG tag. All fields are optional; only
supplied fields are modified.
properties:
og_title:
type: string
maxLength: 255
og_description:
type: string
og_image:
type: string
maxLength: 512
og_type:
type: string
enum:
- article
- website
- product
- profile
- book
- music.song
- music.album
- video.movie
- video.episode
- video.other
og_video:
type: string
format: uri
maxLength: 512
seo_title:
type: string
maxLength: 70
meta_description:
type: string
maxLength: 200
robots:
type: string
maxLength: 100
canonical_url:
type: string
format: uri
maxLength: 512
language:
type: string
maxLength: 7
published:
type: integer
enum: [0, 1]
ErrorResponse:
type: object
description: JSON:API error response
properties:
errors:
type: array
items:
type: object
properties:
title:
type: string
example: Not Found
status:
type: integer
example: 404
detail:
type: string
example: "Item not found."
responses:
BadRequest:
description: Invalid request data
content:
application/vnd.api+json:
schema:
$ref: "#/components/schemas/ErrorResponse"
example:
errors:
- title: Bad Request
status: 400
detail: "Content type is required."
Unauthorized:
description: Missing or invalid API token
content:
application/vnd.api+json:
schema:
$ref: "#/components/schemas/ErrorResponse"
example:
errors:
- title: Forbidden
status: 403
detail: "You are not authorised to access this resource."
NotFound:
description: Resource not found
content:
application/vnd.api+json:
schema:
$ref: "#/components/schemas/ErrorResponse"
example:
errors:
- title: Not Found
status: 404
detail: "Item not found."