Skip to main content
Skills are AI processing pipelines that run on an asset after upload. Each skill is a sequence of steps — for example, generating a caption, writing alt text, or extracting structured metadata from an image. Results are stored on the asset as derivatives (processed image versions) and structured results (AI-generated metadata), so they are always available when you retrieve the asset.

Prerequisites

At least one AI provider profile must be configured and set to active. You can manage AI providers at /ai-providers in the admin console or through the /api/v1/system/ai/providers endpoints.
If no active AI provider profile exists, skill execution will fail. Configure your AI provider (API base URL, API key, and model name) before running skills.

List available skills

To see which skills are available on your instance:
curl -X GET https://your-api-host/api/v1/assets/skills \
  -H "Authorization: Bearer <access_token>"
Response:
{
  "data": [
    {
      "skillName": "enrich",
      "description": "Generates a caption, alt text, and structured metadata for an image.",
      "steps": ["caption", "alt-text", "structured-metadata"]
    }
  ]
}

Run a skill manually

To run a skill on a specific asset, send a POST request to /api/v1/assets/{id}/skills/{skillName}/run:
curl -X POST https://your-api-host/api/v1/assets/<asset-id>/skills/enrich/run \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{}'

Response

The response includes a full execution summary with the result of each step, as well as the updated asset record:
{
  "data": {
    "succeeded": true,
    "skillName": "enrich",
    "steps": [
      { "name": "caption", "succeeded": true, "errorMessage": null },
      { "name": "alt-text", "succeeded": true, "errorMessage": null },
      { "name": "structured-metadata", "succeeded": true, "errorMessage": null }
    ],
    "asset": {
      "id": "01956f8d-88e4-7c6a-a8f1-5f235293db7a",
      "status": "ready",
      "structuredResults": [
        {
          "kind": "caption",
          "payloadJson": "{\"caption\": \"A tabby cat sitting on a wooden floor.\"}",
          "createdAtUtc": "2026-04-08T10:05:00Z"
        }
      ],
      "derivatives": [],
      "latestExecutionSummary": {
        "executionId": "01956fa0-0000-7000-0000-000000000001",
        "skillName": "enrich",
        "triggerSource": "manual",
        "startedAtUtc": "2026-04-08T10:05:00Z",
        "completedAtUtc": "2026-04-08T10:05:03Z",
        "succeeded": true,
        "steps": [
          { "stepName": "caption", "succeeded": true, "errorMessage": null }
        ]
      }
    }
  }
}
If a step fails, succeeded is false for that step and errorMessage contains the reason. The overall succeeded field reflects whether all steps completed successfully.

Automatic enrichment on upload

When you upload an asset with runEnrichment: true (the default), NekoHub automatically runs enrichment in the background after the file is stored. You do not need to call the skill endpoint manually. The asset’s latestExecutionSummary field on subsequent GET /api/v1/assets/{id} requests shows the enrichment outcome, including which steps ran and whether they succeeded.
Pass runEnrichment: false during upload to skip automatic enrichment. You can then run a skill manually at any time, or choose a different skill than the default enrichment pipeline.

Where results are stored

Skill execution produces two types of output, both attached to the asset:
Output typeFieldDescription
Processed image versionsderivativesAlternative renditions of the original (e.g., thumbnails, resized versions) generated by image-processing steps
AI-generated metadatastructuredResultsJSON payloads containing captions, alt text, tags, or other model output
Both are returned when you fetch a single asset with GET /api/v1/assets/{id}.