Unionavatar
Introduction
Union Avatars develop and provide identity tools for the Metaverse through Avatars. We work with cutting-edge technologies such as Computer vision, Artificial Intelligence, and blockchain to deliver our product for upcoming immersive paradigms.
The Union Avatars is a tool for companies and users to manage their digital identity as an avatar on web3.0. Current API is an early approach to onboard people as an avatar in the metaverse. It allows them to create photorealistic 3D avatars from 2D Selfie pictures and be part of this digital revolution.
You can find more about us on our website.
Now we will run over some of the main concepts of our API.
Authentication
In the beginning, you will need to have your credentials. You can request for it in this page.
Organizations
First, you need to get familiarized with Organizations. Organizations in Union Avatars are the ones that contain users, clothes and avatars. When you get access to our API, you will receive one as well as and an administrator account (for that organization).
It is required to have an organization in order to use our API.
Whenever one of your users logins, creates an avatar, changes clothes,... All of that must be done under your organization.
To use your it, simply pass the Organization ID in the login endpoint. Here is an example:
Put attention to "Content-Type" header value in this request, it must be "application/x-www-form-urlencoded".
- JavaScript
- Python
- C#
js
const url = 'https://api.unionavatars.com/v2/login'const myHeaders = new Headers()myHeaders.append('Content-Type', 'application/x-www-form-urlencoded')const login = () => {const res = fetch(url, {method: 'POST',headers: myHeaders,body: JSON.stringify({username: '<YOUR_USERNAME>', password: '<YOUR_PASSWORD>', organization: '<YOUR_ORG_ID>'})}).then(res => res.json()).then(res => console.log(res))}login()
js
const url = 'https://api.unionavatars.com/v2/login'const myHeaders = new Headers()myHeaders.append('Content-Type', 'application/x-www-form-urlencoded')const login = () => {const res = fetch(url, {method: 'POST',headers: myHeaders,body: JSON.stringify({username: '<YOUR_USERNAME>', password: '<YOUR_PASSWORD>', organization: '<YOUR_ORG_ID>'})}).then(res => res.json()).then(res => console.log(res))}login()
python
import requestsurl = 'https://api.unionavatars.com/v2/login'headers = {'Content-Type': 'application/x-www-form-urlencoded'}data = {'username': 'user@example.com','password': 'string''organization': 'string'}response = requests.post(url, headers=headers, data=data )
python
import requestsurl = 'https://api.unionavatars.com/v2/login'headers = {'Content-Type': 'application/x-www-form-urlencoded'}data = {'username': 'user@example.com','password': 'string''organization': 'string'}response = requests.post(url, headers=headers, data=data )
using(var client = new HttpClient()) { var url = "https://api.unionavatars.com/v2/login"; var body = new[] { new KeyValuePair<string, string>("username", '<YOUR_USERNAME>'), new KeyValuePair<string, string>("password", '<YOUR_PASSWORD>'), new KeyValuePair<string, string>("organization", '<YOUR_ORG_ID>'), }; var res = await client.PostAsync(url, new FormUrlEncodedContent(body)); return await res.Content.ReadAsStringAsync(); }
using(var client = new HttpClient()) { var url = "https://api.unionavatars.com/v2/login"; var body = new[] { new KeyValuePair<string, string>("username", '<YOUR_USERNAME>'), new KeyValuePair<string, string>("password", '<YOUR_PASSWORD>'), new KeyValuePair<string, string>("organization", '<YOUR_ORG_ID>'), }; var res = await client.PostAsync(url, new FormUrlEncodedContent(body)); return await res.Content.ReadAsStringAsync(); }
Bearer Token
Most of endpoints are protected by bearer JWT, so you will need to provide a specific Authorization header in each request you make to our API.
What you can and can't do will depend on the user's role. The following action require admin previlages.
- Manage users
- Manage organization
- Manage API Keys
Some API calls require an API Key instead of a bearer token, such as creating users in your account!
Response model from /login endpoint looks like:
{ "access_token": "<YOUR_TOKEN>", "token_type": "bearer" }
{ "access_token": "<YOUR_TOKEN>", "token_type": "bearer" }
So the header you will need to add to your request is:
- JavaScript
- Python
- C#
js
const myHeaders = new Headers();myHeaders.append('Authorization', 'Bearer <ACCESS_TOKEN>');
js
const myHeaders = new Headers();myHeaders.append('Authorization', 'Bearer <ACCESS_TOKEN>');
python
{'Authorization': 'Bearer <ACCESS_TOKEN>'}
python
{'Authorization': 'Bearer <ACCESS_TOKEN>'}
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "<ACCESS_TOKEN>")
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "<ACCESS_TOKEN>")
API Keys
The last concept about auth that we will cover are API Keys. API Keys can be used instead of Bearer Tokens to act in behalf of an admin user. More importantly, some endpoints will only allow you to use an API Key.
The following endpoints can only be called with an API Key:
- POST /users
In order to request an api key you would need to follow the previous section to retrive your token
The creation and retrieving of API keys requires admin privilege
To create a new key, send a POST request to https://api.unionavatars.com/v2/keys with the following payload:
{ "description": "My very fist API Key", "expire_at": "2030-11-11T11:11:11", "scope": "basic" }
{ "description": "My very fist API Key", "expire_at": "2030-11-11T11:11:11", "scope": "basic" }
- JavaScript
- Python
- C#
js
const url = 'https://api.unionavatars.com/v2/keys'const myHeaders = new Headers()myHeaders.append('Authorization', 'Bearer <ACCESS_TOKEN>')myHeaders.append('Content-Type', 'application/json')const gen_api_key = () => {const res = fetch(url, {method: 'POST',heders: myHeaders,body: JSON.stringify({"description": "My very fist API Key","expire_at": "2030-11-11T11:11:11","scope": "basic"})}).then(res => res.json()).then(res => console.log(res))}getBodies()
js
const url = 'https://api.unionavatars.com/v2/keys'const myHeaders = new Headers()myHeaders.append('Authorization', 'Bearer <ACCESS_TOKEN>')myHeaders.append('Content-Type', 'application/json')const gen_api_key = () => {const res = fetch(url, {method: 'POST',heders: myHeaders,body: JSON.stringify({"description": "My very fist API Key","expire_at": "2030-11-11T11:11:11","scope": "basic"})}).then(res => res.json()).then(res => console.log(res))}getBodies()
python
import requestsurl = 'https://api.unionavatars.com/v2/keys'headers = {'Authorization': 'Bearer <ACCESS_TOKEN>','Content-Type': 'application/json'}data = {"description": "My very fist API Key","expire_at": "2030-11-11T11:11:11","scope": "basic"}response = requests.post(url, headers=headers, data=data)
python
import requestsurl = 'https://api.unionavatars.com/v2/keys'headers = {'Authorization': 'Bearer <ACCESS_TOKEN>','Content-Type': 'application/json'}data = {"description": "My very fist API Key","expire_at": "2030-11-11T11:11:11","scope": "basic"}response = requests.post(url, headers=headers, data=data)
using(var client = new HttpClient()) { var url = "https://api.unionavatars.com/v2/keys"; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "<ACCESS_TOKEN>"); string data_json = JsonConvert.SerializeObject( new { description = "My very fist API Key", expire_at = "2030-11-11T11:11:11", scope = "basic" } ); var body = new StringContent(data_json, Encoding.UTF8, "application/json"); var res = await client.PostAsync(url, body); return await res.Content.ReadAsStringAsync(); }
using(var client = new HttpClient()) { var url = "https://api.unionavatars.com/v2/keys"; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "<ACCESS_TOKEN>"); string data_json = JsonConvert.SerializeObject( new { description = "My very fist API Key", expire_at = "2030-11-11T11:11:11", scope = "basic" } ); var body = new StringContent(data_json, Encoding.UTF8, "application/json"); var res = await client.PostAsync(url, body); return await res.Content.ReadAsStringAsync(); }
Try to keep a record of your api-keys. So in case of any leak attempt you can delete the key.
If you have any issues related to authorization, you can check the troubleshooting section.
Assets (Avatar's clothes and accesories)
Asset classification
Union Avatars API has 3 types of assets:
- Outfits
- Garments
- Hairs
Each asset belongs to a Collection which designates a group of assets that have some kind of relation (theme, campaign,...).
On top of that we have the Catalogues, which are a container of collections and individual assets. Each organization has one catalogue by default, and that catalogue is what will be displayed during the avatar creation. For most of the cases, you will only need to use this.
Collections are also connected to Brands, which are only used for better organization.
The previous classification only applies to Outfits and Garments. Hairstyles do not apply.
We know this got confusing, but we will go over each one of these now.
Pagination
The following endpoints return paginated data for an easier display on the frontend. This section is not about a specific router but a new way to work with almost all the GET endpoints you will interact with.
The structure of the response of the endpoints that can be paginated will be like the following:
json
{"items": [ ... ],"total": integer,"page": integer,"size": integer,"pages": integer}
json
{"items": [ ... ],"total": integer,"page": integer,"size": integer,"pages": integer}
Inside the array items key you will find the elements you are requesting for.
The total is the number of the total elements you can get from this endpoint (not the number of elements actually recovered).
The page is the pointer that tells you from which page are you retrieving the information. This value will be always 1 or greater. Default is 1.
The size is an integer between 1 and 100 that you can use to specify how much elements you want get for each page. The default is 50.
The pages tell you the number of pages you can request for. It is a quick math total/size.
When making a request to any paginated endpoint you can provide size and page as query parameter to control what elements you want to retrieve.
Outfits, Garments & Hairs
The way to fetch the available assets for your organization is to use your catalogue. If you don't know your catalogue ID, you can perform a simple GET request to /catalogues.
The endpoint we are going to use is: /catalogues/assets/{catalogue_id}
This endpoint has multiple parameters that let you filter which assets you want to receive. Remember that the output will always be paginated (as explained in the previous section).
The main parameters of the endpoint are the following:
- asset_type: outfits || garments || hairs
- gender: male || female
- version: v{versionNumber}
- brand_id: {brandId}
- collection_id: {collectionID}
Here's an example on how to get a list of available outfits for male avatars:
- JavaScript
- Python
- C#
js
const url = 'https://api.unionavatars.com/v2/catalogues/assets/{catalogue_id}'const myHeaders = new Headers()myHeaders.append('Authorization', 'Bearer <ACCESS_TOKEN>')myHeaders.append('Content-Type', 'application/json')const gen_api_key = () => {const res = fetch(url, {method: 'GET',heders: myHeaders,body: JSON.stringify({"asset_type": "outfits","gender": "male"})}).then(res => res.json()).then(res => console.log(res))}getBodies()
js
const url = 'https://api.unionavatars.com/v2/catalogues/assets/{catalogue_id}'const myHeaders = new Headers()myHeaders.append('Authorization', 'Bearer <ACCESS_TOKEN>')myHeaders.append('Content-Type', 'application/json')const gen_api_key = () => {const res = fetch(url, {method: 'GET',heders: myHeaders,body: JSON.stringify({"asset_type": "outfits","gender": "male"})}).then(res => res.json()).then(res => console.log(res))}getBodies()
python
import requestsurl = 'https://api.unionavatars.com/v2/catalogues/assets/{catalogue_id}'headers = {'Authorization': 'Bearer <ACCESS_TOKEN>','Content-Type': 'application/json'}data = {"asset_type": "outfits","gender": "male"}response = requests.get(url, headers=headers, data=data)
python
import requestsurl = 'https://api.unionavatars.com/v2/catalogues/assets/{catalogue_id}'headers = {'Authorization': 'Bearer <ACCESS_TOKEN>','Content-Type': 'application/json'}data = {"asset_type": "outfits","gender": "male"}response = requests.get(url, headers=headers, data=data)
using(var client = new HttpClient()) { var url = "https://api.unionavatars.com/v2/catalogues/assets/{catalogue_id}"; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "<ACCESS_TOKEN>"); string data_json = JsonConvert.SerializeObject( new { "asset_type": "outfits", "gender": "male" } ); var body = new StringContent(data_json, Encoding.UTF8, "application/json"); var res = await client.GetAsync(url, body); return await res.Content.ReadAsStringAsync(); }
using(var client = new HttpClient()) { var url = "https://api.unionavatars.com/v2/catalogues/assets/{catalogue_id}"; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "<ACCESS_TOKEN>"); string data_json = JsonConvert.SerializeObject( new { "asset_type": "outfits", "gender": "male" } ); var body = new StringContent(data_json, Encoding.UTF8, "application/json"); var res = await client.GetAsync(url, body); return await res.Content.ReadAsStringAsync(); }
To get hairs and garments you can use the same snippet, just change the asset_type parameter.
Assembling an outfit with Garments
Instead of using a full outfit, you can compose a new one using Garments. Garments are individual pieces of clothing that can be combined to create an outfit.
There are 4 types of garments:
- Accessories (optional)
- Top
- Bottom
- Shoes
You can get a list of the available garments by following the instructions in the previous section.
To create a new outfit from a set of garments you need to make a POST request to /outfits/assemble:
- JavaScript
- Python
- C#
js
const url = 'https://api.unionavatars.com/v2/outfits/assemble'const myHeaders = new Headers()myHeaders.append('Authorization', 'Bearer <ACCESS_TOKEN>')myHeaders.append('Content-Type', 'application/json')const gen_api_key = () => {const res = fetch(url, {method: 'POST',heders: myHeaders,body: JSON.stringify({"name": "string","top_id": "string","bottom_id": "string","shoes_id": "string","accessories_id": "string"})}).then(res => res.json()).then(res => console.log(res))}getBodies()
js
const url = 'https://api.unionavatars.com/v2/outfits/assemble'const myHeaders = new Headers()myHeaders.append('Authorization', 'Bearer <ACCESS_TOKEN>')myHeaders.append('Content-Type', 'application/json')const gen_api_key = () => {const res = fetch(url, {method: 'POST',heders: myHeaders,body: JSON.stringify({"name": "string","top_id": "string","bottom_id": "string","shoes_id": "string","accessories_id": "string"})}).then(res => res.json()).then(res => console.log(res))}getBodies()
python
import requestsurl = 'https://api.unionavatars.com/v2/outfits/assemble'headers = {'Authorization': 'Bearer <ACCESS_TOKEN>','Content-Type': 'application/json'}data = {"name": "string","top_id": "string","bottom_id": "string","shoes_id": "string","accessories_id": "string"}response = requests.post(url, headers=headers, data=data)
python
import requestsurl = 'https://api.unionavatars.com/v2/outfits/assemble'headers = {'Authorization': 'Bearer <ACCESS_TOKEN>','Content-Type': 'application/json'}data = {"name": "string","top_id": "string","bottom_id": "string","shoes_id": "string","accessories_id": "string"}response = requests.post(url, headers=headers, data=data)
using(var client = new HttpClient()) { var url = "https://api.unionavatars.com/v2/outfits/assemble"; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "<ACCESS_TOKEN>"); string data_json = JsonConvert.SerializeObject( new { "name": "string", "top_id": "string", "bottom_id": "string", "shoes_id": "string", "accessories_id": "string" } ); var body = new StringContent(data_json, Encoding.UTF8, "application/json"); var res = await client.PostAsync(url, body); return await res.Content.ReadAsStringAsync(); }
using(var client = new HttpClient()) { var url = "https://api.unionavatars.com/v2/outfits/assemble"; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "<ACCESS_TOKEN>"); string data_json = JsonConvert.SerializeObject( new { "name": "string", "top_id": "string", "bottom_id": "string", "shoes_id": "string", "accessories_id": "string" } ); var body = new StringContent(data_json, Encoding.UTF8, "application/json"); var res = await client.PostAsync(url, body); return await res.Content.ReadAsStringAsync(); }
Creating Avatars
Generate head
When creating an avatar, you have to provide an outfit and a head. The head is created from a 2D selfie image.
Image as a Base64 string
The accepted input format for the 2D selfie is a base 64 image. We support the most used image file extensions (jpg, png, jpeg,...).
Here's an example implementation to convert a local image to a Base64 string:
- JavaScript
- Python
- C#
js
function readFileAsDataURI(e) {var file = e.target.files[0];if (!file) {return;}var reader = new FileReader();return reader.readAsDataURL(file);}// In this example content comes from input in UI where user loads an image.// But you can use a BLOB class whenever it comes instead.document.getElementById('file-input').addEventListener('change', readSingleFile, false);
js
function readFileAsDataURI(e) {var file = e.target.files[0];if (!file) {return;}var reader = new FileReader();return reader.readAsDataURL(file);}// In this example content comes from input in UI where user loads an image.// But you can use a BLOB class whenever it comes instead.document.getElementById('file-input').addEventListener('change', readSingleFile, false);
python
import base64with open('/path/to/your/selfie', 'rb') as img:encoded_string = base64.b64encode(img.read()).decode('utf-8')print(encoded_string)
python
import base64with open('/path/to/your/selfie', 'rb') as img:encoded_string = base64.b64encode(img.read()).decode('utf-8')print(encoded_string)
byte[] img = System.IO.File.ReadAllBytes("/path/to/your/selfie"); string base64ImageRepresentation = Convert.ToBase64String(img); return base64ImageRepresentation;
byte[] img = System.IO.File.ReadAllBytes("/path/to/your/selfie"); string base64ImageRepresentation = Convert.ToBase64String(img); return base64ImageRepresentation;
Head creation request
Once you have your base64 selfie ready, just send a POST request to /heads endpoint.
An example of how to perform this request:
Give your head a hairstyle by adding the parameter "hair_id"
- JavaScript
- Python
- C#
js
const url = 'https://api.unionavatars.com/v2/heads'const myHeaders = new Headers()myHeaders.append('Authorization', 'Bearer <ACCESS_TOKEN>')myHeaders.append('Content-Type', 'application/json')const createHead = () => {const res = fetch(url, {method: 'POST',headers: myHeaders,body: JSON.stringify({'name': 'string','selfie_img': 'string (base64)','hair_id': 'string'})}).then(res => res.json()).then(res => console.log(res))}createHead()
js
const url = 'https://api.unionavatars.com/v2/heads'const myHeaders = new Headers()myHeaders.append('Authorization', 'Bearer <ACCESS_TOKEN>')myHeaders.append('Content-Type', 'application/json')const createHead = () => {const res = fetch(url, {method: 'POST',headers: myHeaders,body: JSON.stringify({'name': 'string','selfie_img': 'string (base64)','hair_id': 'string'})}).then(res => res.json()).then(res => console.log(res))}createHead()
python
import requestsurl = 'https://api.unionavatars.com/v2/heads'headers = {'Authorization': 'Bearer <ACCESS_TOKEN>','Content-Type': 'application/json'}data = {'name': 'string','selfie_img': 'string (base64)','hair_id': 'string'}response = requests.post(url, headers=headers, data=data)
python
import requestsurl = 'https://api.unionavatars.com/v2/heads'headers = {'Authorization': 'Bearer <ACCESS_TOKEN>','Content-Type': 'application/json'}data = {'name': 'string','selfie_img': 'string (base64)','hair_id': 'string'}response = requests.post(url, headers=headers, data=data)
using(var client = new HttpClient()) { var url = "https://api.unionavatars.com/v2/heads"; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "<ACCESS_TOKEN>"); string data_json = JsonConvert.SerializeObject( new { 'name': 'string', 'selfie_img': 'string (base64)', 'hair_id': 'string' } ); var body = new StringContent(data_json, Encoding.UTF8, "application/json"); var res = await client.PostAsync(url, body); return await res.Content.ReadAsStringAsync(); }
using(var client = new HttpClient()) { var url = "https://api.unionavatars.com/v2/heads"; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "<ACCESS_TOKEN>"); string data_json = JsonConvert.SerializeObject( new { 'name': 'string', 'selfie_img': 'string (base64)', 'hair_id': 'string' } ); var body = new StringContent(data_json, Encoding.UTF8, "application/json"); var res = await client.PostAsync(url, body); return await res.Content.ReadAsStringAsync(); }
The value of field "id" from the response is the value you have to store to use in the following request.
When you create a head, its stored for you so you can use the same head with different outfits.
Create avatar request payload
You only need three values to create a new avatar: A name, a selfie image or a head ID and an outfit ID.
The name field in the request is a descriptive string that helps you to identify your avatar when getting the list of them.
The image field (named "img") is a base64 string type. If you want to try you can use online tools.
The outfit ID field is a UUID string that you obtained from the available assets endpoint.
We recommend avoid sending "img" field and send a head_id that you created in the step above. The head_id value is a UUID string.
{ "name": "<YOUR_AMAZING_AVATAR_NAME>", "head_id": "<HEAD_UUID>", "outfit_id": "<OUTFIT_UUID>", "output_format": "fbx | glb" }
{ "name": "<YOUR_AMAZING_AVATAR_NAME>", "head_id": "<HEAD_UUID>", "outfit_id": "<OUTFIT_UUID>", "output_format": "fbx | glb" }
The default output format is "glb", so if you want that format you just not provide the field in the request's payload. For more information about the request's payload model to create avatar, you can check detailed documentation of the endpoint
Send request to create avatar
If you have followed the previous steps, you are ready to create your first avatar. It's as simple as sending a POST request to /avatars.
Here is an example implementation:
- JavaScript
- Python
- C#
js
const url = 'https://api.unionavatars.com/v2/avatars'const myHeaders = new Headers()myHeaders.append('Authorization', 'Bearer <ACCESS_TOKEN>')myHeaders.append('Content-Type', 'application/json')const createAvatar = () => {const res = fetch(url, {method: 'POST',headers: myHeaders,body: JSON.stringify({'name': '<YOUR_AMAZING_AVATAR_NAME>','head_id': '<HEAD_UUID>','outfit_id': '<OUTFIT_UUID>','output_format': 'fbx | glb'})}).then(res => res.json()).then(res => console.log(res))}createAvatar()
js
const url = 'https://api.unionavatars.com/v2/avatars'const myHeaders = new Headers()myHeaders.append('Authorization', 'Bearer <ACCESS_TOKEN>')myHeaders.append('Content-Type', 'application/json')const createAvatar = () => {const res = fetch(url, {method: 'POST',headers: myHeaders,body: JSON.stringify({'name': '<YOUR_AMAZING_AVATAR_NAME>','head_id': '<HEAD_UUID>','outfit_id': '<OUTFIT_UUID>','output_format': 'fbx | glb'})}).then(res => res.json()).then(res => console.log(res))}createAvatar()
python
import requestsurl = 'https://api.unionavatars.com/v2/avatars'headers = {'Authorization': 'Bearer <ACCESS_TOKEN>','Content-Type': 'application/json'}data = {'name': '<YOUR_AMAZING_AVATAR_NAME>','head_id': '<HEAD_UUID>','outfit_id': '<OUTFIT_UUID>','output_format': 'fbx | glb'}response = requests.post(url, headers=headers, data=data)
python
import requestsurl = 'https://api.unionavatars.com/v2/avatars'headers = {'Authorization': 'Bearer <ACCESS_TOKEN>','Content-Type': 'application/json'}data = {'name': '<YOUR_AMAZING_AVATAR_NAME>','head_id': '<HEAD_UUID>','outfit_id': '<OUTFIT_UUID>','output_format': 'fbx | glb'}response = requests.post(url, headers=headers, data=data)
using(var client = new HttpClient()) { var url = "https://api.unionavatars.com/v2/avatars"; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "<ACCESS_TOKEN>"); object avatar = new { 'name': '<YOUR_AMAZING_AVATAR_NAME>', 'head_id': '<HEAD_UUID>', 'outfit_id': '<OUTFIT_UUID>', 'output_format': 'fbx | glb' }; var body = new StringContent(JsonConvert.SerializeObject(avatar), Encoding.UTF8, "application/json"); var res = await client.PostAsync(url, body); return await res.Content.ReadAsStringAsync(); }
using(var client = new HttpClient()) { var url = "https://api.unionavatars.com/v2/avatars"; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "<ACCESS_TOKEN>"); object avatar = new { 'name': '<YOUR_AMAZING_AVATAR_NAME>', 'head_id': '<HEAD_UUID>', 'outfit_id': '<OUTFIT_UUID>', 'output_format': 'fbx | glb' }; var body = new StringContent(JsonConvert.SerializeObject(avatar), Encoding.UTF8, "application/json"); var res = await client.PostAsync(url, body); return await res.Content.ReadAsStringAsync(); }
This request will return you the avatar object containing fields like "id" and "url". You can obtain this avatar in the future with its ID or do other operations on it.
The url provides you direct access to your 3D avatar file. With a GET request, you can download your avatar ready to use in games, any other platforms!
If you need more details regarding these fields, you can check the documentation of the endpoint
Notes
Timeout when creating avatar
You might face a timeout upon your request to create an avatar. This event is due to a long line on the request. Usually, if the request starts and you lose the connection, the avatar creation process might resolve your request.
In case of this situation, you can check your last avatar generated has the same name.
To get your last avatar you need to make a GET request to /avatars/last endpoint.
- JavaScript
- Python
- C#
js
const url = 'https://api.unionavatars.com/v2/avatars/last'const myHeaders = new Headers()myHeaders.append('Authorization', 'Bearer <ACCESS_TOKEN>')myHeaders.append('Content-Type', 'application/json')const getLastAvatar = () => {const res = fetch(url, {headers: myHeaders,}).then(res => res.json()).then(res => console.log(res))}getLastAvatar()
js
const url = 'https://api.unionavatars.com/v2/avatars/last'const myHeaders = new Headers()myHeaders.append('Authorization', 'Bearer <ACCESS_TOKEN>')myHeaders.append('Content-Type', 'application/json')const getLastAvatar = () => {const res = fetch(url, {headers: myHeaders,}).then(res => res.json()).then(res => console.log(res))}getLastAvatar()
python
import requestsurl = 'https://api.unionavatars.com/v2/avatars/last'headers = {'Authorization': 'Bearer <ACCESS_TOKEN>','Content-Type': 'application/json'}response = requests.get(url, headers=headers)
python
import requestsurl = 'https://api.unionavatars.com/v2/avatars/last'headers = {'Authorization': 'Bearer <ACCESS_TOKEN>','Content-Type': 'application/json'}response = requests.get(url, headers=headers)
using(var client = new HttpClient()) { var url = "https://api.unionavatars.com/v2/avatars/last"; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "<ACCESS_TOKEN>"); var res = await client.GetAsync(url); return await res.Content.ReadAsStringAsync(); }
using(var client = new HttpClient()) { var url = "https://api.unionavatars.com/v2/avatars/last"; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "<ACCESS_TOKEN>"); var res = await client.GetAsync(url); return await res.Content.ReadAsStringAsync(); }
Troubleshooting
General problems
I have created avatars in my account but I'm not seeing them (in SDK or your own implementation)
As explained in the authentication section, avatars always belong to an organization. When you use our website to generate avatars, those avatars belong to the Union Avatars organization, therefore if you login using a different organization you won't be able to see them.
So, when you create avatars, make sure to do it from you organization. Either using our Unity SDK or by requesting it to the API.
Authentication problems
When you are making a request to our API and you are receiving a 401 or 403 you are having troubles with authentication you provided.
Could not validate credentials
If you are getting an 401 response with a body
{ "detail": "Could not validate credentials" }
{ "detail": "Could not validate credentials" }
There are many reasons causing this response:
You are sending correct request, but your token expired. In that case, you can create a new token as explained in login section
Your token is not valid. You are sending a request containing an Authorization header with the correct format, but your token value is not the same as you generated when you logged in. Maybe you changed the characters in the string or added/removed the values (like \n if you are making copy-paste).
Not autheticated
If you are getting an 401 response with a body
{ "detail": "Not authenticated" }
{ "detail": "Not authenticated" }
You are missing the Authorization header in your request, or it is malformed. To solve this issue, make sure you send your request with an Authorization header with the correct format and valid token value.
Authorization="Bearer <ACCESS_TOKEN>"
Authorization="Bearer <ACCESS_TOKEN>"
Errors 422: request's body validations
Getting a 422 status code response means that you are trying to send a payload with one or more invalid values.
Most common cases of errors in payload are:
- Missing required parameter
- Provide not a valid type of data for some param. For example, providing a string in a field that expects a boolean.
If you check your request body and everything seems ok, maybe you are missing "Content-Type: application/json" header.
When you don't provide this header, the API will send you a 422 response saying you are missing all required fields.
How to read 422 response
The JSON structure from 422 responses can be quite confusing. It's gonna look similar to this:
{ "detail": [ { "loc": [ "body", "name" ], "msg": "field required", "type": "value_error.missing" }, { "loc": [ "body", "img" ], "msg": "Value is not valid base64", "type": "type_error.base64" } ] }
{ "detail": [ { "loc": [ "body", "name" ], "msg": "field required", "type": "value_error.missing" }, { "loc": [ "body", "img" ], "msg": "Value is not valid base64", "type": "type_error.base64" } ] }
You always gonna have a "detail" array containing all field validations failed.
For each validation failed you will find a "loc" array with two values. The first value is the place where parameter validation failed. In this example is in the body of the request (other values could be "param" or "path"). The second value will tell you which field are referred to. In this example we are missing "name" required field and providing a non base64 string for "img" when creating an avatar.
You also will have a "msg" and "type" strings indicating which is the specific error. "msg" field will be more human readable while "type" is the internal error type of the application (you usually gonna ignore this last field).
Contact support
We are open to any suggestion or bug report!
You also can contact us to request access to our API or to request some help.
You can contact with us by sending a mail to techsupport@unionavatars.com.
Authentication
Security Scheme Type: | oauth2 |
---|---|
OAuth Flow (password): | Token URL: login Scopes: |
Security Scheme Type: | apiKey |
---|---|
Header parameter name: | access_token |