curl --request POST \
--url https://api.budgetpixel.com/v1/poses/{handle}/views \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"azimuth": 135,
"elevation": 30,
"figure": "woman"
}
'import requests
url = "https://api.budgetpixel.com/v1/poses/{handle}/views"
payload = {
"azimuth": 135,
"elevation": 30,
"figure": "woman"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({azimuth: 135, elevation: 30, figure: 'woman'})
};
fetch('https://api.budgetpixel.com/v1/poses/{handle}/views', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.budgetpixel.com/v1/poses/{handle}/views",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'azimuth' => 135,
'elevation' => 30,
'figure' => 'woman'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.budgetpixel.com/v1/poses/{handle}/views"
payload := strings.NewReader("{\n \"azimuth\": 135,\n \"elevation\": 30,\n \"figure\": \"woman\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.budgetpixel.com/v1/poses/{handle}/views")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"azimuth\": 135,\n \"elevation\": 30,\n \"figure\": \"woman\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.budgetpixel.com/v1/poses/{handle}/views")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"azimuth\": 135,\n \"elevation\": 30,\n \"figure\": \"woman\"\n}"
response = http.request(request)
puts response.read_body{
"picture": {
"angle": "front",
"azimuth": 0,
"elevation": 0,
"figure": "woman",
"height": 1152,
"id": "<string>",
"label": "Back left · from above",
"made_by": "<string>",
"mention": "@seiza_pose.back",
"thumbnail_url": "<string>",
"url": "<string>",
"view": true,
"width": 864
},
"status": "made"
}{
"job": {
"angle": "az135_el30",
"attempts": 1,
"azimuth": 135,
"created_at": "2023-11-07T05:31:56Z",
"credits_charged": 123,
"elevation": 30,
"figure": "woman",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"label": "Back right · from above",
"landed_picture": {
"angle": "front",
"azimuth": 0,
"elevation": 0,
"figure": "woman",
"height": 1152,
"id": "<string>",
"label": "Back left · from above",
"made_by": "<string>",
"mention": "@seiza_pose.back",
"thumbnail_url": "<string>",
"url": "<string>",
"view": true,
"width": 864
},
"message": "Back right · from above is in the library now, for everyone.",
"picture": {
"angle": "front",
"azimuth": 0,
"elevation": 0,
"figure": "woman",
"height": 1152,
"id": "<string>",
"label": "Back left · from above",
"made_by": "<string>",
"mention": "@seiza_pose.back",
"thumbnail_url": "<string>",
"url": "<string>",
"view": true,
"width": 864
},
"pose_id": "<string>",
"status": "queued",
"updated_at": "2023-11-07T05:31:56Z"
},
"joined": true,
"price": 40,
"status": "making"
}{
"error": {
"code": "model_not_available",
"message": "<string>",
"type": "invalid_request_error"
}
}{
"error": {
"code": "model_not_available",
"message": "<string>",
"type": "invalid_request_error"
}
}{
"error": "A new angle costs 40 credits.",
"error_code": "insufficient_credits",
"required_credits": 40
}{
"error": {
"code": "model_not_available",
"message": "<string>",
"type": "invalid_request_error"
}
}{
"error": {
"code": "model_not_available",
"message": "<string>",
"type": "invalid_request_error"
}
}{
"error": "Back right has not come out right for this pose yet. Try a nearby angle.",
"error_code": "angle_unavailable"
}{
"error": "You can ask for 50 new angles a day. Try again tomorrow.",
"error_code": "daily_cap"
}Make a pose view
A pose seen from another place on the Camera Angles globe. Pick one of the pose’s
mannequins (figure) and a place (azimuth, elevation): the mannequin’s front picture
is turned there, a check confirms it is the same pose and where the camera landed, and the
view joins the library for everyone, credited to you. There are no private views.
Places. azimuth is where the camera stands around the figure, in steps of 45: 0
front, 45 front right, 90 right side (the camera moved to the viewer’s right, so the
figure’s left side shows), 135 back right, 180 back, 225 back left, 270 left side
and 315 front left (where the pose’s own three-quarter picture sits). elevation is how
high it stands: 0 eye level, 30 from above, 60 from high above.
Answer: 200 with status: made and the picture when the place already has a view
(free). Otherwise 202 with status: making and the job: follow it with
GET /v1/poses/views/{id} every 10 to 15 seconds until status is done (the view is in
picture), missed or failed. A view usually takes 30 to 90 seconds. One job per place:
when someone is already making the view you ask for, you join their job (joined: true)
and pay nothing.
Using it: a pose’s answer (GET /v1/poses/{handle}) lists every view with its
mention. Write it after a character in a prompt: @seiza_pose.back, or .right,
.left, .front_right, .back_left, .back_right, .three_quarter, .above (front
from above), .top (front from high above), or a code like .az135_el30.
Price: 40 credits, charged only when the view lands where you asked (a second try is
free when the first misses). A try that lands on another empty place is kept there for
everyone, free (landed_picture on the job). Up to 50 new views a day (429 past that).
curl --request POST \
--url https://api.budgetpixel.com/v1/poses/{handle}/views \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"azimuth": 135,
"elevation": 30,
"figure": "woman"
}
'import requests
url = "https://api.budgetpixel.com/v1/poses/{handle}/views"
payload = {
"azimuth": 135,
"elevation": 30,
"figure": "woman"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({azimuth: 135, elevation: 30, figure: 'woman'})
};
fetch('https://api.budgetpixel.com/v1/poses/{handle}/views', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.budgetpixel.com/v1/poses/{handle}/views",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'azimuth' => 135,
'elevation' => 30,
'figure' => 'woman'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.budgetpixel.com/v1/poses/{handle}/views"
payload := strings.NewReader("{\n \"azimuth\": 135,\n \"elevation\": 30,\n \"figure\": \"woman\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.budgetpixel.com/v1/poses/{handle}/views")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"azimuth\": 135,\n \"elevation\": 30,\n \"figure\": \"woman\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.budgetpixel.com/v1/poses/{handle}/views")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"azimuth\": 135,\n \"elevation\": 30,\n \"figure\": \"woman\"\n}"
response = http.request(request)
puts response.read_body{
"picture": {
"angle": "front",
"azimuth": 0,
"elevation": 0,
"figure": "woman",
"height": 1152,
"id": "<string>",
"label": "Back left · from above",
"made_by": "<string>",
"mention": "@seiza_pose.back",
"thumbnail_url": "<string>",
"url": "<string>",
"view": true,
"width": 864
},
"status": "made"
}{
"job": {
"angle": "az135_el30",
"attempts": 1,
"azimuth": 135,
"created_at": "2023-11-07T05:31:56Z",
"credits_charged": 123,
"elevation": 30,
"figure": "woman",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"label": "Back right · from above",
"landed_picture": {
"angle": "front",
"azimuth": 0,
"elevation": 0,
"figure": "woman",
"height": 1152,
"id": "<string>",
"label": "Back left · from above",
"made_by": "<string>",
"mention": "@seiza_pose.back",
"thumbnail_url": "<string>",
"url": "<string>",
"view": true,
"width": 864
},
"message": "Back right · from above is in the library now, for everyone.",
"picture": {
"angle": "front",
"azimuth": 0,
"elevation": 0,
"figure": "woman",
"height": 1152,
"id": "<string>",
"label": "Back left · from above",
"made_by": "<string>",
"mention": "@seiza_pose.back",
"thumbnail_url": "<string>",
"url": "<string>",
"view": true,
"width": 864
},
"pose_id": "<string>",
"status": "queued",
"updated_at": "2023-11-07T05:31:56Z"
},
"joined": true,
"price": 40,
"status": "making"
}{
"error": {
"code": "model_not_available",
"message": "<string>",
"type": "invalid_request_error"
}
}{
"error": {
"code": "model_not_available",
"message": "<string>",
"type": "invalid_request_error"
}
}{
"error": "A new angle costs 40 credits.",
"error_code": "insufficient_credits",
"required_credits": 40
}{
"error": {
"code": "model_not_available",
"message": "<string>",
"type": "invalid_request_error"
}
}{
"error": {
"code": "model_not_available",
"message": "<string>",
"type": "invalid_request_error"
}
}{
"error": "Back right has not come out right for this pose yet. Try a nearby angle.",
"error_code": "angle_unavailable"
}{
"error": "You can ask for 50 new angles a day. Try again tomorrow.",
"error_code": "daily_cap"
}Authorizations
API key as a bearer token: Authorization: Bearer bpx_live_xxx
Path Parameters
The pose's handle, with or without the @ (seiza_pose).
Body
Where the camera stands around the figure: 0 front, 45 front right, 90 right side (the figure's left side shows), 135 back right, 180 back, 225 back left, 270 left side, 315 front left.
0, 45, 90, 135, 180, 225, 270, 315 0 eye level, 30 from above, 60 from high above.
0, 30, 60 The mannequin to turn. A mention sends the one that matches the character's gender (the woman when it isn't known).
woman, man