> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.morphiaone.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.morphiaone.ai/_mcp/server.

# Read what a Makeup try-on may name

GET https://api.morphiaone.ai/v1/makeup/capabilities

Lists every makeup category with whether a try-on may name it now, and for each
enabled one its options (kind, bounds, default, accepted values), its texture ids
and its known limitations: accepted options that do not do what their name
suggests on the current engine. It is built from the same declaration the request
model is, so a category, value or texture listed here is one a try-on accepts.
`declaration_digest` changes when what may be sent changes, never with a
deployment; `runtime` is the deployment's declared identity, `unknown` where it
declared none. A refused try-on never echoes the value it refused: read the
accepted values here.

Reference: https://docs.morphiaone.ai/api-reference/endpoints/makeup/capabilities-get

## Authentication

- `X-API-Key` header (required) — API key for one environment of your account. Keep server-side; never expose in browser clients.

## Response

### 200

Successful Response

- `categories` (list of CategoryCapability, required)
- `certification` (string, required)
- `contract` ("makeup", required)
- `custom` (CustomProfiles, required)
- `declaration_digest` (string, required)
- `designs` (list of DesignCapability, required)
- `limits` (LimitCapabilities, required)
- `modes` (ModeCapabilities, required) — The public request modes; explicit products are not one.
- `runtime` (RuntimeIdentity, required)

## Errors

### 401 Unauthorized Error

Missing or invalid API key

- `error` (ErrorDetail, required)

### 403 Forbidden Error

API key lacks the makeup scope

- `error` (ErrorDetail, required)

## Types

### CategoryCapability

- `category` (string, required)
- `enabled` (boolean, required)
- `custom` (CustomCapability, optional, nullable) — Whether a ``mode: "custom"`` application is accepted for the category, and how.
- `default_design` (string, optional, nullable)
- `default_placement` (string, optional, nullable)
- `limitations` (list of Limitation, optional, nullable)
- `options` (list of OptionCapability, optional, nullable)
- `placements` (list of string, optional, nullable)

### CustomProfiles

- `profiles_digest` (string, required)

### DesignCapability

The current version of a design: what a ``design`` product names.

- `application_fields` (list of CustomOptionCapability, required)
- `category` (string, required)
- `digest` (string, required)
- `id` (string, required)
- `label` (string, required)
- `roles` (map from string to DesignRoleCapability, required)
- `shorthand_role` (string, required, nullable)
- `status` (string, required)
- `version` (integer, required)

### LimitCapabilities

- `max_applications` (integer, required)
- `max_look_entries` (integer, required)
- `max_look_recipe_bytes` (integer, required)
- `max_variant_application_definitions` (integer, required)

### ModeCapabilities

The public request modes; explicit products are not one.

- `custom` (ModeCapability, required)
- `look` (ModeCapability, required)
- `variant` (ModeCapability, required)

### RuntimeIdentity

- `application_git_sha` (string, required)
- `image_digest` (string, required)

### ErrorDetail

- `code` (string, required)
- `message` (string, required)
- `request_id` (string, required)
- `details` (ErrorDetailDetails, optional)
- `doc_url` (string, optional, nullable)
- `retryable` (boolean, optional, nullable)

### CustomCapability

Whether a ``mode: "custom"`` application is accepted for the category, and how.

- `enabled` (boolean, required)
- `options` (list of CustomOptionCapability, optional, nullable)
- `profile` (CustomProfileRef, optional, nullable)

### Limitation

- `code` (string, required)
- `field` (string, required)
- `text` (string, required)

### OptionCapability

- `field` (string, required)
- `kind` (enum, required)
  - Allowed values: `boolean`, `color`, `enum`, `integer`, `number`, `range`, `shade`, `shades`, `texture`, `unit`
- `required` (boolean, required)
- `default` (OptionCapabilityDefault, optional, nullable)
- `format` (string, optional, nullable)
- `max` (double, optional, nullable)
- `min` (double, optional, nullable)
- `step` (double, optional, nullable)
- `textures` (list of TextureChoice, optional, nullable)
- `values` (list of string, optional, nullable)

### CustomOptionCapability

- `default` (string, required)
- `field` (string, required)
- `values` (list of string, required)

### DesignRoleCapability

- `fields` (map from string to DesignFieldCapability, required)
- `label` (string, required)

### ModeCapability

- `available` (boolean, required)

### ErrorDetailDetails

- map from string to any
- list of map from string to any

### CustomProfileRef

- `digest` (string, required)
- `id` (string, required)
- `version` (integer, required)

### OptionCapabilityDefault

- double
- boolean
- string

### TextureChoice

- `id` (string, required)
- `label` (string, required)
- `slots` (integer, required, nullable)

### DesignFieldCapability

- `type` ("color", required)

## Examples

**Response**

```json
{
  "categories": [
    {
      "category": "blush",
      "enabled": true,
      "custom": {
        "enabled": true,
        "options": [
          {
            "default": "medium",
            "field": "intensity",
            "values": [
              "medium",
              "strong"
            ]
          }
        ],
        "profile": {
          "digest": "sha256:57bb4f7dfe1f0e110b226b1ed94f1c568e09590769065e696c7ee4acd1433456",
          "id": "blush.standard",
          "version": 1
        }
      },
      "default_design": "blush.classic",
      "limitations": [
        {
          "code": "zero_opacity_renders_nothing",
          "field": "opacity",
          "text": "opacity 0 renders no product; leave the product out instead."
        }
      ],
      "options": [
        {
          "field": "color",
          "kind": "color",
          "required": true,
          "format": "#RRGGBB"
        },
        {
          "field": "opacity",
          "kind": "number",
          "required": false,
          "default": 1,
          "max": 1,
          "min": 0,
          "step": 0.01
        },
        {
          "field": "texture",
          "kind": "texture",
          "required": true,
          "textures": [
            {
              "id": "blush.1",
              "label": "Blush 1",
              "slots": null
            },
            {
              "id": "blush.2",
              "label": "Blush 2",
              "slots": null
            }
          ]
        },
        {
          "field": "glitter.texture",
          "kind": "texture",
          "required": true,
          "textures": [
            {
              "id": "glitter.1",
              "label": "Glitter 1",
              "slots": null
            },
            {
              "id": "glitter.2",
              "label": "Glitter 2",
              "slots": null
            }
          ]
        },
        {
          "field": "glitter.opacity",
          "kind": "unit",
          "required": false,
          "default": 1,
          "max": 1,
          "min": 0
        }
      ]
    },
    {
      "category": "eyebrow",
      "enabled": false
    }
  ],
  "certification": "931866fbb6b6",
  "contract": "makeup",
  "custom": {
    "profiles_digest": "sha256:066c4e8e65379e4f8c6bbe11d6563352dbc5de18d677597b4e9e8c2b556d56f4"
  },
  "declaration_digest": "sha256:0000000000000000000000000000000000000000000000000000000000000000",
  "designs": [
    {
      "application_fields": [
        {
          "default": "medium",
          "field": "intensity",
          "values": [
            "medium",
            "strong"
          ]
        }
      ],
      "category": "blush",
      "digest": "sha256:31ae55110423d21a5b7ee178e1bd9e139dd45e053ec2e470a0b5503bba043a3f",
      "id": "blush.classic",
      "label": "Blush",
      "roles": {
        "primary": {
          "fields": {
            "color": {
              "type": "color"
            }
          },
          "label": "Colour"
        }
      },
      "shorthand_role": "primary",
      "status": "published",
      "version": 1
    },
    {
      "application_fields": [],
      "category": "lipstick",
      "digest": "sha256:dad1c4f57c3b69a54dc1517f1dfd4037aac14e4496c5793fa1046a558c7f41d8",
      "id": "lip.ombre",
      "label": "Ombre lipstick",
      "roles": {
        "inner": {
          "fields": {
            "color": {
              "type": "color"
            }
          },
          "label": "Inner colour"
        },
        "outer": {
          "fields": {
            "color": {
              "type": "color"
            }
          },
          "label": "Outer colour"
        }
      },
      "shorthand_role": null,
      "status": "published",
      "version": 1
    }
  ],
  "limits": {
    "max_applications": 11,
    "max_look_entries": 11,
    "max_look_recipe_bytes": 16384,
    "max_variant_application_definitions": 8
  },
  "modes": {
    "custom": {
      "available": true
    },
    "look": {
      "available": true
    },
    "variant": {
      "available": true
    }
  },
  "runtime": {
    "application_git_sha": "4f1c2e9a7b3d",
    "image_digest": "unknown"
  }
}
```

**SDK Code**

```python Makeup_capabilitiesGet_example
import requests

url = "https://api.morphiaone.ai/v1/makeup/capabilities"

headers = {"X-API-Key": "<apiKey>"}

response = requests.get(url, headers=headers)

print(response.json())
```

```javascript Makeup_capabilitiesGet_example
const url = 'https://api.morphiaone.ai/v1/makeup/capabilities';
const options = {method: 'GET', headers: {'X-API-Key': '<apiKey>'}};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Makeup_capabilitiesGet_example
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.morphiaone.ai/v1/makeup/capabilities"

	req, _ := http.NewRequest("GET", url, nil)

	req.Header.Add("X-API-Key", "<apiKey>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Makeup_capabilitiesGet_example
require 'uri'
require 'net/http'

url = URI("https://api.morphiaone.ai/v1/makeup/capabilities")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<apiKey>'

response = http.request(request)
puts response.read_body
```

```java Makeup_capabilitiesGet_example
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.get("https://api.morphiaone.ai/v1/makeup/capabilities")
  .header("X-API-Key", "<apiKey>")
  .asString();
```

```php Makeup_capabilitiesGet_example
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://api.morphiaone.ai/v1/makeup/capabilities', [
  'headers' => [
    'X-API-Key' => '<apiKey>',
  ],
]);

echo $response->getBody();
```

```csharp Makeup_capabilitiesGet_example
using RestSharp;

var client = new RestClient("https://api.morphiaone.ai/v1/makeup/capabilities");
var request = new RestRequest(Method.GET);
request.AddHeader("X-API-Key", "<apiKey>");
IRestResponse response = client.Execute(request);
```

```swift Makeup_capabilitiesGet_example
import Foundation

let headers = ["X-API-Key": "<apiKey>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://api.morphiaone.ai/v1/makeup/capabilities")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```