Unionavatar
Introduction v1
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.
We suggest you follow our quickstart guide to get familiarized with our API integration.
Quickstart
We will walk you through the processes to create your first avatar using our API! In the beginning, you will need to have your username and password provided by us. If you don't have your credentials already, please reach out to support team.
Login
First, you will need to get an access token that you will have to include in all request headers when requesting to our API.
To get your token, you will need to make a POST request to https://api.unionavatars.com/login.
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/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>'})}).then(res => res.json()).then(res => console.log(res))}login()
js
const url = 'https://api.unionavatars.com/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>'})}).then(res => res.json()).then(res => console.log(res))}login()
python
import requestsurl = 'https://api.unionavatars.com/login'headers = {'Content-Type': 'application/x-www-form-urlencoded'}data = {'username': 'user@example.com','password': 'string'}response = requests.post(url, headers=headers, data=data )
python
import requestsurl = 'https://api.unionavatars.com/login'headers = {'Content-Type': 'application/x-www-form-urlencoded'}data = {'username': 'user@example.com','password': 'string'}response = requests.post(url, headers=headers, data=data )
using(var client = new HttpClient()) { var url = "https://api.unionavatars.com/login"; var body = new[] { new KeyValuePair<string, string>("username", '<YOUR_USERNAME>'), new KeyValuePair<string, string>("password", '<YOUR_PASSWORD>'), }; 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/login"; var body = new[] { new KeyValuePair<string, string>("username", '<YOUR_USERNAME>'), new KeyValuePair<string, string>("password", '<YOUR_PASSWORD>'), }; var res = await client.PostAsync(url, new FormUrlEncodedContent(body)); return await res.Content.ReadAsStringAsync(); }
Auth headers
Most of our endpoints are protected by bearer JWT, so you will need to provide a specific Authorization header in each request you make to our API.
Sending a request that doesn't require authorization with Authorization header does not cause an error, so we recommend you to implement an interceptor/middleware that includes
your credentials in all of your requests.
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>")
You can also use "token_type" returned from request to /login as first value of your Authorization header. In case the token type changes in future.
- JavaScript
- Python
- C#
js
const myHeaders = new Headers();myHeaders.append('Authorization', '<TOKEN_TYPE> <ACCESS_TOKEN>');
js
const myHeaders = new Headers();myHeaders.append('Authorization', '<TOKEN_TYPE> <ACCESS_TOKEN>');
python
{'Authorization': '<TOKEN_TYPE> <ACCESS_TOKEN>'}
python
{'Authorization': '<TOKEN_TYPE> <ACCESS_TOKEN>'}
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("<TOKEN_TYPE>", "<ACCESS_TOKEN>");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("<TOKEN_TYPE>", "<ACCESS_TOKEN>");
If you have any issues related to authorization, you can check the troubleshooting section.
Get bodies
When you create an avatar, you have to provide a body ID.
To generate the avatar with the body, you need to pass its ID in the "body" field.
You can get the list of available bodies by sending a get request to the "/bodies" endpoint.
You need to attach your auth token to the request's headers, as we explained in the previous section.
- JavaScript
- Python
- C#
js
const url = 'https://api.unionavatars.com/bodies'const myHeaders = new Headers()myHeaders.append('Authorization', 'Bearer <ACCESS_TOKEN>')myHeaders.append('Content-Type', 'application/json')const getBodies = () => {const res = fetch(url, {heders: myHeaders}).then(res => res.json()).then(res => console.log(res))}getBodies()
js
const url = 'https://api.unionavatars.com/bodies'const myHeaders = new Headers()myHeaders.append('Authorization', 'Bearer <ACCESS_TOKEN>')myHeaders.append('Content-Type', 'application/json')const getBodies = () => {const res = fetch(url, {heders: myHeaders}).then(res => res.json()).then(res => console.log(res))}getBodies()
python
import requestsurl = 'https://api.unionavatars.com/bodies'headers = {'Authorization': 'Bearer <ACCESS_TOKEN>','Content-Type': 'application/json'}response = requests.get(url, headers=headers)
python
import requestsurl = 'https://api.unionavatars.com/bodies'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/bodies"; 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/bodies"; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "<ACCESS_TOKEN>"); var res = await client.GetAsync(url); return await res.Content.ReadAsStringAsync(); }
You can store the list of bodies that have been returned and provide the specific ID of the body later for avatar creation. For further information about this respons take a look at bodies section.
(Optional) Validate selfie image
When creating a head, API will respond with a 3D model even if selfie image provided is not good enough. In order to avoid wasting resources creating non usable avatars, you can validate the image sending a request before creating avatar.
The endpoint is /validation/head. It is a POST requests and only takes a body with a parameter named "img". The type of the field "img" is a base64 string.
You will need also provide authentication in headers as you did in previous requests.
Example of how to perform this request
- JavaScript
- Python
- C#
js
const url = 'https://api.unionavatars.com/validation/head'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({'img': '<IMAGE_BASE64_STRING>'})}).then(res => res.json()).then(res => console.log(res))}createAvatar()
js
const url = 'https://api.unionavatars.com/validation/head'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({'img': '<IMAGE_BASE64_STRING>'})}).then(res => res.json()).then(res => console.log(res))}createAvatar()
python
import requestsurl = 'https://api.unionavatars.com/validation/head'headers = {'Authorization': 'Bearer <ACCESS_TOKEN>','Content-Type': 'application/json'}data = {'img': '<IMAGE_BASE64_STRING>'}response = requests.post(url, headers=headers, data=data)
python
import requestsurl = 'https://api.unionavatars.com/validation/head'headers = {'Authorization': 'Bearer <ACCESS_TOKEN>','Content-Type': 'application/json'}data = {'img': '<IMAGE_BASE64_STRING>'}response = requests.post(url, headers=headers, data=data)
using(var client = new HttpClient()) { var url = "https://api.unionavatars.com/validation/head"; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "<ACCESS_TOKEN>"); string image_json = JsonConvert.SerializeObject(new { img = "<IMAGE_BASE64_STRING>" }); var body = new StringContent(image_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/validation/head"; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "<ACCESS_TOKEN>"); string image_json = JsonConvert.SerializeObject(new { img = "<IMAGE_BASE64_STRING>" }); var body = new StringContent(image_json, Encoding.UTF8, "application/json"); var res = await client.PostAsync(url, body); return await res.Content.ReadAsStringAsync(); }
You can find more information about validations here
Generate head
When creating an avatar, you have to provide a body and a head. The head is created from a 2D selfie image.
Here, we provide an example of constructing a base64 string from an image. We provide this in different syntaxes. However, the way to approach this will depend on your platform conditions. The main objective is to provide base64 string regardless of image entry or language.
The start point of this example is you have a selfie stored file in your system standard format as jpg, png, jpeg, etc.
- 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;
To create a head you have to send a POST request to /heads endpoint.
Example of how to perform this request
- JavaScript
- Python
- C#
js
const url = 'https://api.unionavatars.com/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': 'My first head','selfie_img': '<IMAGE_BASE64_STRING>'})}).then(res => res.json()).then(res => console.log(res))}createHead()
js
const url = 'https://api.unionavatars.com/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': 'My first head','selfie_img': '<IMAGE_BASE64_STRING>'})}).then(res => res.json()).then(res => console.log(res))}createHead()
python
import requestsurl = 'https://api.unionavatars.com/heads'headers = {'Authorization': 'Bearer <ACCESS_TOKEN>','Content-Type': 'application/json'}data = {'name': 'My first head','selfie_img': '<IMAGE_BASE64_STRING>'}response = requests.post(url, headers=headers, data=data)
python
import requestsurl = 'https://api.unionavatars.com/heads'headers = {'Authorization': 'Bearer <ACCESS_TOKEN>','Content-Type': 'application/json'}data = {'name': 'My first head','selfie_img': '<IMAGE_BASE64_STRING>'}response = requests.post(url, headers=headers, data=data)
using(var client = new HttpClient()) { var url = "https://api.unionavatars.com/heads"; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "<ACCESS_TOKEN>"); string image_json = JsonConvert.SerializeObject(new { selfie_img = "<IMAGE_BASE64_STRING>", name = "My first head" }); var body = new StringContent(image_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/heads"; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "<ACCESS_TOKEN>"); string image_json = JsonConvert.SerializeObject(new { selfie_img = "<IMAGE_BASE64_STRING>", name = "My first head" }); var body = new StringContent(image_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 bodies.
You can skip this step and provide the selfie image directly when sending the request to create avatar, but we highly recommend create the head yourself. When the head es autogenerated when creating the full avatar you cannot choose the head name.
Create avatar request payload
You only need three values to create a new avatar: A name, selfie image or head ID and a body 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.
But 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.
The body ID field is a UUID string that you obtained from a previous step.
{ "name": "<YOUR_AMAZING_AVATAR_NAME>", "head_id": "<HEAD_UUID>", "body_id": "<BODY_UUID>", "output_format": "fbx | glb" }
{ "name": "<YOUR_AMAZING_AVATAR_NAME>", "head_id": "<HEAD_UUID>", "body_id": "<BODY_UUID>", "output_format": "fbx | glb" }
You can skip "output_format"! 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
With your credentials ready in your Authorization header and the payload you just created in last section, you can send an HTTP request to obtain your avatar.
- JavaScript
- Python
- C#
js
const url = 'https://api.unionavatars.com/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>','img': '<IMAGE_BASE64_STRING>','body': '<BODY_UUID>','output_format': 'fbx | glb'})}).then(res => res.json()).then(res => console.log(res))}createAvatar()
js
const url = 'https://api.unionavatars.com/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>','img': '<IMAGE_BASE64_STRING>','body': '<BODY_UUID>','output_format': 'fbx | glb'})}).then(res => res.json()).then(res => console.log(res))}createAvatar()
python
import requestsurl = 'https://api.unionavatars.com/avatars'headers = {'Authorization': 'Bearer <ACCESS_TOKEN>','Content-Type': 'application/json'}data = {'name': '<YOUR_AMAZING_AVATAR_NAME>','img': '<IMAGE_BASE64_STRING>','body': '<BODY_UUID>','output_format': 'fbx | glb'}response = requests.post(url, headers=headers, data=data)
python
import requestsurl = 'https://api.unionavatars.com/avatars'headers = {'Authorization': 'Bearer <ACCESS_TOKEN>','Content-Type': 'application/json'}data = {'name': '<YOUR_AMAZING_AVATAR_NAME>','img': '<IMAGE_BASE64_STRING>','body': '<BODY_UUID>','output_format': 'fbx | glb'}response = requests.post(url, headers=headers, data=data)
using(var client = new HttpClient()) { var url = "https://api.unionavatars.com/avatars"; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "<ACCESS_TOKEN>"); object avatar = new { name = "<YOUR_AMAZING_AVATAR_NAME>", img = "<IMAGE_BASE64_STRING>", body = "<BODY_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/avatars"; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "<ACCESS_TOKEN>"); object avatar = new { name = "<YOUR_AMAZING_AVATAR_NAME>", img = "<IMAGE_BASE64_STRING>", body = "<BODY_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 "avatar_link". You can obtain this avatar in the future with its ID or do other operations on it. The avatar link 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/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/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/avatars/last'headers = {'Authorization': 'Bearer <ACCESS_TOKEN>','Content-Type': 'application/json'}response = requests.get(url, headers=headers)
python
import requestsurl = 'https://api.unionavatars.com/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/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/avatars/last"; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "<ACCESS_TOKEN>"); var res = await client.GetAsync(url); return await res.Content.ReadAsStringAsync(); }
Advanced docs
Will be available soon....
Troubleshooting
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 |