Превращает фото в рельеф для 3D-печати: модель в STL и GLB и карта глубины. Цена — 130 ₽ за рельеф или карту глубины.
Общая документация Public API · API-ключ можно создать в настройках аккаунта
Meshy Relief превращает фотографию в рельеф для 3D-печати и фрезеровки: значок, медальон, портрет питомца, надпись на сувенире, накладку на кружку или браслет. В ответе приходят готовая модель в GLB и STL и 16-битная карта глубины. Размер задаётся в миллиметрах. В наших пробах STL приходил в этом масштабе и замкнутым, без дыр в сетке.
Сценарии:
relief - 3D-рельеф с картой глубины;depth_map - только карта глубины, без модели.Вызов создаёт асинхронную операцию: сразу приходит её id, готовые файлы забираются отдельным запросом. В наших пробах рельеф и карта глубины строились от 1,5 до 4 минут. Цена - 130 ₽ за запуск.
POST /api/v1/operationsAuthorization: Bearer brth_...id и статус queued. Результат забирается по id.Сценарий выбирается полем generation_type: relief или depth_map. Если поле не передано, строится рельеф.
{
"tool": "meshy-relief",
"input": {
"generation_type": "relief",
"image_url": "https://cdn.example.com/celtic-medallion-1.png",
"variant": "low",
"carving_mode": "emboss",
"size_mm": 60
}
}
tool - slug нейросети, всегда "meshy-relief".input - параметры запуска, прямо внутри input, без дополнительной вложенности.depth_map не учитываются и на цену не влияют.| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
generation_type | string | Нет | relief - рельеф с картой глубины (используется, если поле не передано), depth_map - только карта глубины. |
image_url | string (url) | Да | Фото: JPG, JPEG, PNG или WebP, до 20 МБ. Лучше всего подходит один чёткий объект на однотонном фоне. |
variant | string | Нет | Глубина рельефа: low - неглубокий, передаёт мелкие детали (узоры, значки, печати), high - глубокий, объёмная лепка (питомцы, портреты, персонажи). |
carving_mode | string | Нет | Только для relief. emboss - ближние части выступают, engrave - глубина переворачивается и ближние части вырезаны внутрь. |
size_mm | number | Нет | Только для relief. Длина длинной стороны фото в миллиметрах до изгиба, от 10 до 500. Без основания модель может быть меньше: обрезается по объекту. |
remove_base | boolean | Нет | Только для relief. true вырезает фон и не строит основание. |
bend_mode | string | Нет | Только для relief. Изгиб дугой: off - без изгиба, convex - выпуклый, concave - вогнутый. |
bend_axis | string | Нет | При bend_mode convex или concave. xz - загибаются левый и правый края, yz - верхний и нижний. |
bend_angle | number | Нет | При bend_mode convex или concave. Угол изгиба в градусах, от 1 до 360. |
use_advanced |
Круглый орнамент размером 60 мм: неглубокий выпуклый рельеф на основании. Самый простой запуск.
curl -X POST https://bratuha.ru/api/v1/operations \
-H "Authorization: Bearer brth_ваш_ключ" \
-H "Content-Type: application/json" \
-d '{
"tool": "meshy-relief",
"input": {
"generation_type": "relief",
"image_url": "https://cdn.example.com/celtic-medallion-1.png",
"variant": "low",
"carving_mode": "emboss",
"size_mm": 60
}
}'
const response = await fetch('https://bratuha.ru/api/v1/operations', {
method: 'POST',
headers: {
Authorization: 'Bearer brth_ваш_ключ',
'Content-Type': 'application/json',
},
body: JSON.stringify({
tool: 'meshy-relief',
input: {
generation_type: 'relief',
image_url: 'https://cdn.example.com/celtic-medallion-1.png',
variant: 'low',
carving_mode: 'emboss',
size_mm: 60,
},
}),
})
const data = await response.json()
import requests
response = requests.post(
'https://bratuha.ru/api/v1/operations',
headers={
'Authorization': 'Bearer brth_ваш_ключ',
'Content-Type': 'application/json',
},
json={
'tool': 'meshy-relief',
'input': {
'generation_type': 'relief',
'image_url': 'https://cdn.example.com/celtic-medallion-1.png',
'variant': 'low',
'carving_mode': 'emboss',
'size_mm': 60,
},
},
timeout=30,
)
print(response.status_code)
print(response.json())
Голова льва на дуге: глубокий рельеф шириной 100 мм, вогнутый изгиб на 60 градусов, загибаются левый и правый края.
curl -X POST https://bratuha.ru/api/v1/operations \
-H "Authorization: Bearer brth_ваш_ключ" \
-H "Content-Type: application/json" \
-d '{
"tool": "meshy-relief",
"input": {
"generation_type": "relief",
"image_url": "https://cdn.example.com/lion-head-1.jpg",
"variant": "high",
"carving_mode": "emboss",
"size_mm": 100,
"bend_mode": "concave",
"bend_axis": "xz",
"bend_angle": 60
}
}'
const response = await fetch('https://bratuha.ru/api/v1/operations', {
method: 'POST',
headers: {
Authorization: 'Bearer brth_ваш_ключ',
'Content-Type': 'application/json',
},
body: JSON.stringify({
tool: 'meshy-relief',
input: {
generation_type: 'relief',
image_url: 'https://cdn.example.com/lion-head-1.jpg',
variant: 'high',
carving_mode: 'emboss',
size_mm: 100,
bend_mode: 'concave',
bend_axis: 'xz',
bend_angle: 60,
},
}),
})
const data = await response.json()
import requests
response = requests.post(
'https://bratuha.ru/api/v1/operations',
headers={
'Authorization': 'Bearer brth_ваш_ключ',
'Content-Type': 'application/json',
},
json={
'tool': 'meshy-relief',
'input': {
'generation_type': 'relief',
'image_url': 'https://cdn.example.com/lion-head-1.jpg',
'variant': 'high',
'carving_mode': 'emboss',
'size_mm': 100,
'bend_mode': 'concave',
'bend_axis': 'xz',
'bend_angle': 60,
},
},
timeout=30,
)
print(response.status_code)
print(response.json())
Фон вырезается, остаётся только сам объект. Лучше всего работает с одним объектом на однотонном фоне.
curl -X POST https://bratuha.ru/api/v1/operations \
-H "Authorization: Bearer brth_ваш_ключ" \
-H "Content-Type: application/json" \
-d '{
"tool": "meshy-relief",
"input": {
"generation_type": "relief",
"image_url": "https://cdn.example.com/butterfly-1.jpg",
"variant": "low",
"carving_mode": "emboss",
"size_mm": 80,
"remove_base": true
}
}'
const response = await fetch('https://bratuha.ru/api/v1/operations', {
method: 'POST',
headers: {
Authorization: 'Bearer brth_ваш_ключ',
'Content-Type': 'application/json',
},
body: JSON.stringify({
tool: 'meshy-relief',
input: {
generation_type: 'relief',
image_url: 'https://cdn.example.com/butterfly-1.jpg',
variant: 'low',
carving_mode: 'emboss',
size_mm: 80,
remove_base: true,
},
}),
})
const data = await response.json()
import requests
response = requests.post(
'https://bratuha.ru/api/v1/operations',
headers={
'Authorization': 'Bearer brth_ваш_ключ',
'Content-Type': 'application/json',
},
json={
'tool': 'meshy-relief',
'input': {
'generation_type': 'relief',
'image_url': 'https://cdn.example.com/butterfly-1.jpg',
'variant': 'low',
'carving_mode': 'emboss',
'size_mm': 80,
'remove_base': True,
},
},
timeout=30,
)
print(response.status_code)
print(response.json())
Эмблема вырезана внутрь на 2 мм, основание 2 мм. Дополнительные параметры включаются полем use_advanced.
curl -X POST https://bratuha.ru/api/v1/operations \
-H "Authorization: Bearer brth_ваш_ключ" \
-H "Content-Type: application/json" \
-d '{
"tool": "meshy-relief",
"input": {
"generation_type": "relief",
"image_url": "https://cdn.example.com/wolf-emblem-1.png",
"variant": "low",
"carving_mode": "engrave",
"size_mm": 50,
"use_advanced": true,
"carving_depth_mm": 2,
"base_thickness_mm": 2,
"mesh_resolution": 1024
}
}'
const response = await fetch('https://bratuha.ru/api/v1/operations', {
method: 'POST',
headers: {
Authorization: 'Bearer brth_ваш_ключ',
'Content-Type': 'application/json',
},
body: JSON.stringify({
tool: 'meshy-relief',
input: {
generation_type: 'relief',
image_url: 'https://cdn.example.com/wolf-emblem-1.png',
variant: 'low',
carving_mode: 'engrave',
size_mm: 50,
use_advanced: true,
carving_depth_mm: 2,
base_thickness_mm: 2,
mesh_resolution: 1024,
},
}),
})
const data = await response.json()
import requests
response = requests.post(
'https://bratuha.ru/api/v1/operations',
headers={
'Authorization': 'Bearer brth_ваш_ключ',
'Content-Type': 'application/json',
},
json={
'tool': 'meshy-relief',
'input': {
'generation_type': 'relief',
'image_url': 'https://cdn.example.com/wolf-emblem-1.png',
'variant': 'low',
'carving_mode': 'engrave',
'size_mm': 50,
'use_advanced': True,
'carving_depth_mm': 2,
'base_thickness_mm': 2,
'mesh_resolution': 1024,
},
},
timeout=30,
)
print(response.status_code)
print(response.json())
Без 3D-модели: на выходе одна 16-битная карта глубины в PNG.
curl -X POST https://bratuha.ru/api/v1/operations \
-H "Authorization: Bearer brth_ваш_ключ" \
-H "Content-Type: application/json" \
-d '{
"tool": "meshy-relief",
"input": {
"generation_type": "depth_map",
"image_url": "https://cdn.example.com/portrait-1.jpg",
"variant": "high"
}
}'
const response = await fetch('https://bratuha.ru/api/v1/operations', {
method: 'POST',
headers: {
Authorization: 'Bearer brth_ваш_ключ',
'Content-Type': 'application/json',
},
body: JSON.stringify({
tool: 'meshy-relief',
input: {
generation_type: 'depth_map',
image_url: 'https://cdn.example.com/portrait-1.jpg',
variant: 'high',
},
}),
})
const data = await response.json()
import requests
response = requests.post(
'https://bratuha.ru/api/v1/operations',
headers={
'Authorization': 'Bearer brth_ваш_ключ',
'Content-Type': 'application/json',
},
json={
'tool': 'meshy-relief',
'input': {
'generation_type': 'depth_map',
'image_url': 'https://cdn.example.com/portrait-1.jpg',
'variant': 'high',
},
},
timeout=30,
)
print(response.status_code)
print(response.json())
{
"id": "op_uuid-123",
"status": "queued",
"tool": "meshy-relief",
"cost": 130,
"balance_after": 870,
"created_at": "2026-11-07T14:17:10.364Z"
}
{
"id": "op_uuid-123",
"status": "completed",
"tool": "meshy-relief",
"cost": 130,
"created_at": "2026-11-07T14:17:10.364Z",
"completed_at": "2026-11-07T14:19:10.581Z",
"result": {
"type": "file",
"files": [
{ "url": "https://storage.bratuha.ru/results/meshy-relief/relief.glb", "name": "3D-модель" },
{ "url": "https://storage.bratuha.ru/results/meshy-relief/relief.stl", "name": "Для 3D-печати (STL)" },
{ "url": "https://storage.bratuha.ru/results/meshy-relief/depth.png", "name": "Карта глубины" }
]
},
"error_message": null
}
{
"id": "op_uuid-123",
"status": "completed",
"tool": "meshy-relief",
"cost": 130,
"created_at": "2026-11-07T14:20:31.831Z",
"completed_at": "2026-11-07T14:22:14.446Z",
"result": {
"type": "image",
"urls": ["https://storage.bratuha.ru/results/meshy-relief/depth.png"]
},
"error_message": null
}
Операция завершается статусом failed, result равен null, причина - в error_message. Деньги возвращаются на баланс.
{
"id": "op_uuid-123",
"status": "failed",
"tool": "meshy-relief",
"cost": 130,
"created_at": "2026-11-07T14:17:10.364Z",
"completed_at": "2026-11-07T14:17:24.310Z",
"result": null,
"error_message": "Ваш запрос не прошел модерацию."
}
Сохраните id из ответа на создание и проверяйте операцию по нему:
GET /api/v1/operations/{id}
curl -H "Authorization: Bearer brth_ваш_ключ" \
https://bratuha.ru/api/v1/operations/op_uuid-123
async function waitForRelief(id) {
while (true) {
const res = await fetch(`https://bratuha.ru/api/v1/operations/${id}`, {
headers: { Authorization: 'Bearer brth_ваш_ключ' },
})
const op = await res.json()
if (op.status === 'completed') return op.result
if (op.status === 'failed') throw new Error(op.error_message)
await new Promise((r) => setTimeout(r, 15000))
}
}
Статус одной операции можно запрашивать не чаще раза в секунду, иначе придёт 429 rate_limit_exceeded. Хватает опроса раз в 15-30 секунд.
Формат зависит от сценария.
relief - "type": "file" и массив files, у каждого файла url и name:
name | Что внутри |
|---|---|
3D-модель | модель GLB, для просмотра и 3D-редакторов |
Для 3D-печати (STL) | та же модель в STL, в миллиметрах |
Карта глубины | PNG, 16 бит на канал, оттенки серого, длинная сторона около 2,7-3,2 тысячи точек |
depth_map - "type": "image" и массив urls с одной ссылкой на такой же PNG.
Выбирайте файлы по name, а не по номеру в массиве. Расширение берите из url. Файлы тяжёлые: при mesh_resolution 1024 в наших пробах GLB весил 15-53 МБ, а STL - 31-110 МБ, с изгибом больше. При 2048 с изгибом на 120 градусов GLB весил 211 МБ, а STL - 440 МБ. Скачайте файлы к себе после завершения операции, если они нужны надолго.
Цена фиксированная: 130 ₽ за запуск. Она не зависит от сценария, размера, глубины, изгиба и mesh_resolution.
Сумма списывается при создании операции и приходит в поле cost, остаток баланса - в balance_after. Если операция завершилась ошибкой, деньги возвращаются на баланс, а cost в ответе остаётся суммой запуска.
POST /api/v1/operations не идемпотентен: каждый запрос создаёт новую операцию и списывает деньги. Если ответ не дошёл из-за обрыва сети, не повторяйте запрос автоматически - сначала проверьте баланс или историю в аккаунте.queued, дальше статус проверяется по id.http/https. Адреса localhost, loopback и частные IP не принимаются. Ссылка должна открываться без авторизации и cookies. Расширение в ссылке - .jpg, .jpeg, .png или .webp, иначе API сразу вернёт 400 validation_error и деньги не спишутся.size_mm меньше 10 или больше 500, bend_angle больше 360, removal_threshold больше 0.5) API отклоняет сразу с 400 validation_error, без списания.boolean |
| Нет |
Только для relief. true включает дополнительные настройки ниже. |
carving_depth_mm | number | Нет | При use_advanced: true. Глубина рельефа в миллиметрах, от 0.1 до 50. Если не передать - 3 мм для low и 6 мм для high. |
base_thickness_mm | number | Нет | При use_advanced: true и без remove_base. Толщина основания в миллиметрах, от 0.1 до 50. Если не передать - 1 мм. |
removal_threshold | number | Нет | При use_advanced: true и remove_base: true. Порог вырезания фона по карте глубины, от 0 до 0.5. Если не передать - 0.01. Слишком высокий порог может оставить пустую модель. |
mesh_resolution | number | Нет | При use_advanced: true. Точек сетки на длинной стороне: 512, 1024, 1536 или 2048. Если не передать - 1024. |