Solidus AITECH

L1 + L2 Guide

1. How to get x-product-api-key

  • After purchasing the product, open the usage tab and there will be an access token, which is the value of x-product-api-key. If "-" means it has not been initialized yet, press the Refresh button to initialize it. The Refresh button is also used to reset the access token, at which point the old value will expire.
  • The access token is shared by all products you purchase.
Figure 1.1: Access token isn’t existed

Figure 1.1: Access token isn’t existed

Figure 1.2: Access token is existed

Figure 1.2: Access token is existed

2. Api Guide

2.1 Use product

This API enables users to pass payload from the API /call that the publisher defined.

  • Endpoint
Endpoint/api/v1/user/products/{productId}/use
MethodPOST
  • Header
NameTypeRequired
x-product-api-keyStringY
  • Path
NameTypeDescriptionRequired
productIdIntegerProduct IDY
  • Body
NameTypeDescriptionRequired
methodStringMethod nameY
payloadObjectPayload of methodY
callbackUrlStringN
  • Response
NameTypeDescriptionRequired
codeStringError code. If code = "0", that mean successfulY
messageStringError message. If successful, the message is "success"Y
dataObjectY
> taskIdUUIDIf the method is asynchronous, this field will be returnedN
> statusStringIf the method is asynchronous, this field will be returned and will always be "Pending".N
> … (any fields)If the method is an immediate response, the fields will be returned in the format the publisher has defined for this method in the usage tabN

Case 1: method is a task that needs to be processed asynchronously. These tasks are considered to take a considerable amount of time to process and cannot respond immediately in this api's response.

Figure 2.1.1: The method's flow of operations is asynchronous

Figure 2.1.1: The method's flow of operations is asynchronous

Then, this Api will respond with a taskId and status: "Pending". We will be able to use this taskId to check the result of this request using the Refresh result api. Refer to this example below with a Gif Generator app:

Example Request:

curl -X 'POST' 
  '<host>/api/v1/user/products/53/use' 
  -H 'accept: application/json' 
  -H 'x-product-api-key: <api_key>' 
  -H 'Content-Type: application/json' 
  -d '{
  "method": "text2gif",
  "payload": {
    "prompt": "a cute girl is smiling",
    "height": 512,
    "width": 512
 }
}
'

Example response:

{
    "code": "0",
    "message": "success",
    "data": {
      "taskId": "f9f0f918-3a27-485a-a92f-11a63a2b3630",
      "status": "Pending",
    }
}

Method text2gif will create a gif file from the data received in the payload. This job will definitely take a long time to process. If the system waits for it to finish processing and return it to the user, it will create a bottleneck that clogs the system. Therefore, the system will return a taskId as the task identifier for this request as status: "Pending" to indicate that this task has been recorded and is in process.

Explain further why we save app usage history in 2 ways. There will be 2 api to get app usage results with normal methods (Refresh result, Get use app histories) and 2 api to get app usage results with chat methods (Refresh result, Get use app histories):

  • With standard methods, the returned results will be updated to the request record previously saved in the database.
Figure 2.1.2: Data flow of standard method

Figure 2.1.2: Data flow of standard method

  • With chat methods, the returned results will be saved as a new record in the database. This will help display chat message results easily.
Figure 2.1.3: Data flow of chat method

Figure 2.1.3: Data flow of chat method

Case 2: Method is a job that can be response immediately (for example: querying data from the database, or updating data into the database,...).

Figure 2.1.4: The method's flow of operations responds immediately

Figure 2.1.4: The method's flow of operations responds immediately

It is simply the opposite of case 1. Then all you want from this api will be in its response.

See the example below with the Role Play Chat Bot app

Example Request:

curl -X 'POST' 
  '<host>/api/v1/user/products/324/use' 
  -H 'accept: application/json' 
  -H 'x-product-api-key: <api_key>' 
  -H 'Content-Type: application/json' 
  -d '{
  "method": "listCharacter",
  "payload": {
    "page": 1,
    "size": 10
  }
}
'

Example response:

{
  "code": "0",
  "message": "success",
  "data": {
    "dataType": "META_DATA",
    "data": {
      "characters": [
        {
          "id": "b3971500-f6b5-41b5-a80b-2d9bc9149323",
          "name": "Travel Guide",
          "baseBot": "gpt-3.5-turbo-0125",
          "image": "https://example.com/ecbdbffc-6051-4676-9828-1a15b0d4b187-1049e9d7-1d7a-4890-ad1d-0a94b1917220-1.jpg"
        },
        {
          "id": "335be667-69eb-4bd9-81a2-8f2e110b03d7",
          "name": "Bookworm Betty",
          "baseBot": "llama3-70b-8192",
          "image": "https://example.com/ecbdbffc-6051-4676-9828-1a15b0d4b187-1049e9d7-1d7a-4890-ad1d-0a94b1917220-1.jpg"
        }
      ],
      "total": 2,
      "page": 1,
      "size": 10,
      "pages": 1
    }
  }
}

Role Play Chat Bot app allows users to chat with AI bots, each bot will be able to answer one or more areas well that you need answered. The list of bots has been created by the publisher and stored in the database, so when we need to display the list of bots, we just need to query the database and return the list of available bots. This work is quite light and can be answered immediately in the response of this api. That's why it's called immediate response work. Method listCharacter is an example of such work.

In short, we will have 2 types of data that we can receive from the response of this api.

  1. Asynchronous: The response will always return taskId and status: "Pending". The Refresh result api can be used to get the final result
  2. Synchronous (immediate response): The response will return the data defined by the publisher. There is no taskId and no need to use the Refresh result api to get the final result.

All Jobs (method + payload) will be defined and recorded by the publisher in the Request DTO, Response DTO section in the usage tab. They will also define which methods are synchronous and which methods are asynchronous (immediate response).

In cases where an error occurs:

  • With error validating field method, payload (invalid, missing): Response returns http error 400 (Bad Request)

Example request:

curl -X 'POST' 
  '<host>/api/v1/user/products/324/use' 
  -H 'accept: application/json' 
  -H 'Authorization: Bearer <access_token>' 
  -H 'Content-Type: application/json' 
  -d '{
  "method": "listCharacter"
}
'

Example response:

{
  "statusCode": 400,
  "error": "BadRequestException",
  "message": {
    "payload": "payload should not be empty, payload must be an object"
  }
}
  • If it does not fall within the above two errors, the request will be forwarded to the AI ​​server for processing. Then, if the input does not satisfy the AI ​​app's validation, the system will still return the error http 400 (Bad Request) with code as the error code and message as an error returned by the AI ​​app.

For example below with the Gif Generator App, the App has only one method, text2gif. Passing the method gif_gen is not supported, so AI Server returns the error "message": "unsupported method gif_gen" and "code": "GIF_403"

Example Request:

curl -X 'POST' 
  '<host>/api/v1/user/products/53/use' 
  -H 'accept: application/json' 
  -H 'x-product-api-key: <api_key>' 
  -H 'Content-Type: application/json' 
  -d '{
  "method": "gif_gen",
  "payload": {
    "prompt": "a cute girl is smiling",
    "height": 512,
    "width": 512,
    "negativePrompt": ""
    }
}'

Example response:

{
  "code": "GIF_403",
  "statusCode": 400,
  "error": "BadRequestException",
  "message": "unsupported method gif_gen"
}

Regarding the callbackUrl field.

  • For example, you are developing a Layer 2 app, you have previously purchased a Layer 1 app, and your Layer 2 app needs to use it.
  • You will still need the Use Product, Refresh result or Refresh result for chat app api to be able to use the layer 1 app.
  • However, this requires you to proactively retrieve the results (by using the Refresh result or Refresh result for chat app).
  • To be able to receive results passively, use callbackUrl. Marketplace will proactively call it with the data that is the result of the Layer 1 app.
Figure 2.1.5: The method's flow of operations is asynchronous contain callbackUrl

Figure 2.1.5: The method's flow of operations is asynchronous contain callbackUrl

With the callback api, there are some requirements users need to follow:

  • Http method: POST
  • The request header will contain x-marketplace-token,please review before proceeding to ensure that the request is coming from Marketplace
  • If received, please respond with a status of 200

Note:

  • If it fails or exceeds the timeout (10s), the system will try to call the api callback every 3s up to 3 times.
  • The payload of the callback api will include the following fields:
NameTypeDescriptionRequired
taskIdUUIDTask IDY
responseObjectIs the result returned from the corresponding method when using the Use product api. The format is defined by the publisher in the response DTO of each method in the usage tabY
errorCodeObjectY
> statusStringAn error codeY
> reasonStringSpecifically describe the error that occurredY
extraTypeStringExtra data type. Always is "chat_app"N

2.2 Refresh result

This api is used to receive the return results of the asynchronous method received from the response of the Use product api. Method has extra_type which is not chat_app

  • Endpoint
Endpoint/api/v1/user/products/{productId}/refresh/{taskId}
MethodGET
  • Header
NameTypeRequired
x-product-api-keyStringY
  • Path
NameTypeDescriptionRequired
productIdIntegerProduct IDY
taskIdUUIDTask ID from the response of api Use productY
  • Response
NameTypeDescriptionRequired
codeStringError code. If code = "0", that mean successfulY
messageStringError message. If successful, the message is "success"Y
dataObjectY
> statusStringOne of the following values: "Pending", "Completed", "Failed"Y
> resultObjectIs the result returned from the corresponding method when using the Use product api. The format is defined by the publisher in the response DTO of each method in the usage tabN

Continuing the example with Gif Generator above, below is an example result of method text2gif for the cases Pending, Completed, Failed

Example Request:

curl -X 'GET' 
  '<host>/api/v1/user/products/53/refresh/800e5ab2-a267-4283-95a0-ddd7d095cc63' 
  -H 'accept: application/json' 
  -H 'x-product-api-key: <api_key>'

Example response for Pending:

{
  "code": "0",
  "message": "success",
  "data": {
    "status": "Pending"
  }
}

Example response for Success:

{
  "code": "0",
  "message": "success",
  "data": {
    "status": "Completed",
    "result": {
      "data": "https://example.com/GIFGenerator/5e7e1a54-386a-42d1-a25e-2b30a915e6b1.gif"
    }
  }
}

Example response for Failed:

{
  "code": "0",
  "message": "success",
  "data": {
    "result": {
       "error": [{"message": "Save file error"}]
    },
    "status": "Failed"
  }
}

2.3 Get use app histories

This API is used to get the usage history of asynchronous methods (methods that respond immediately will not be included here).

  • Endpoint
FieldValue
Endpoint/api/v1/user/products/{productId}/usage-histories
MethodGET

  • Header
NameTypeRequired
x-product-api-keyStringY

  • Path
NameTypeDescriptionRequired
productIdIntegerProduct IDY

  • Param
NameTypeDescriptionRequired
pageIntegerPage number to retrieve. Default: 1N
limitIntegerNumber of records per page. Default: 20. Max: 100.N
statusString"Pending", "Completed", "Failed"N
sortByString"id", "createdAt"N
sortDirectionString"ASC", "DESC"N

  • Response
NameTypeDescriptionRequired
codeStringError code. "0" = success.Y
messageStringResponse message. "success" if successful.Y
dataArray<Object>Data records.Y
data.idIntegerUnique record ID.Y
data.taskIdUUIDTask identifier.Y
data.resultObjectIf status = "Completed", contains data from response DTO; if "Failed", includes error info.N
data.statusString"Pending", "Completed", or "Failed".Y
data.dataTypeString"META_DATA", "S3_OBJECT", "HYBRID".N
data.createdAtDateTime (ISO)Timestamp when request was created.Y
data.inputObjectMethod payload input.Y
metaObjectPagination metadata.Y
meta.itemCountIntegerItems on this page.Y
meta.totalItemsIntegerTotal items count.Y
meta.itemsPerPageIntegerItems requested per page.Y
meta.totalPagesIntegerTotal number of pages.Y
meta.currentPageIntegerCurrent page number.Y

Example Request:

curl -X 'GET' 
  '<host>/api/v1/user/products/53/usage-histories?page=1&limit=10' 
  -H 'accept: application/json' 
  -H 'x-product-api-key: <api_key>'

Example Response

{
  "code": "0",
  "message": "success",
  "data": [
    {
      "id": 1172,
      "productId": 53,
      "taskId": "800e5ab2-a267-4283-95a0-ddd7d095cc63",
      "status": "Completed",
      "dataType": "S3_OBJECT",
      "result": {
        "data": "https://example.com/GIFGenerator/5e7e1a54-386a-42d1-a25e-2b30a915e6b1.gif"
      },
      "input": {
        "seed": -1,
        "width": 512,
        "height": 512,
        "prompt": "a cat is running",
        "negativePrompt": "no"
      },
      "createdAt": "2024-06-25T09:49:46.654Z"
    },
    {
      "id": 1173,
      "productId": 53,
      "taskId": "a70560a7-94e5-483f-a49a-024c4409cd8b",
      "status": "Completed",
      "dataType": "S3_OBJECT",
      "result": {
        "data": "https://example.com/GIFGenerator/1ce47aa8-73e6-418c-8b01-f7fcc2c9533d.gif"
      },
      "input": {
        "seed": -1,
        "width": 512,
        "height": 512,
        "prompt": "a girl is smiling and there are trees",
        "negativePrompt": "non"
      },
      "createdAt": "2024-06-25T10:03:56.782Z"
    }
  ],
  "meta": {
    "itemsPerPage": 10,
    "totalItems": 2,
    "currentPage": 1,
    "totalPages": 1
  }
}

2.4 Refresh result for chat app

Like the refresh result api in section 2, this api is also used to receive the return results of the asynchronous method received from the response of the Use product api. But for Method there is extra_type which is chat_app

  • Endpoint
Endpoint/api/v1/user/products/{productId}/chat-app/refresh/{taskId}
MethodGET
  • Header
NameTypeRequired
x-product-api-keyStringY
  • Path
NameTypeDescriptionRequired
productIdIntegerProduct IDY
taskIdUUIDTask ID from response of the api Use productY
  • Param
NameTypeDescriptionRequired
fromStringIs one of the following values: "user", "system"Y
  • Response
NameTypeDescriptionRequired
codeStringError code. If code = "0", that mean successfulY
messageStringError message. If successful, the message is "success"Y
dataObjectY
> idIntegerUnique id của bản ghiY
> taskIdUUIDTask IDY
> sessionIdStringIs the session ID of the app that manages chat by sessionN
> fromStringIs one of the following values: "user", "system"Y
> dataObjectIf from is "user", this field is the data in the payload in the Use product api, otherwise if from is "system", this field is the data in the response according to the format the publisher defines in the usage tabY
> dataTypeStringIs one of the following values: "META_DATA", "S3_OBJECT", "HYBRID"N
> createdAtDate time (ISO)Time which request is createdY

Example Request:

curl -X 'GET' 
'<host>/api/v1/user/products/324/chat-app/refresh/fd6db5ed-428d-4967-9aa0-cf9350330b31?from=system' 
  -H 'accept: application/json' 
  -H 'x-product-api-key: <api_key>'

Example Response:

{
  "code": "0",
  "message": "success",
  "data": {
    "id": 389,
    "taskId": "fd6db5ed-428d-4967-9aa0-cf9350330b31",
    "sessionId": "f16f1631-c540-4fec-bfda-9ea3a20a2cf9",
    "from": "system",
    "data": {
      "data": {
        "image": "",
        "answer": "Hello again! I'm Test, and I'm here to chat about travel and quality control. If you're up for it, let's chat about your bucket list destinations. What's the first place that comes to mind when you dream about your next adventure?"
      },
      "dataType": "META_DATA"
    },
    "dataType": "META_DATA",
    "createdAt": "2024-07-08T09:36:31.110Z"
  }
}

2.5 Get use app histories for chat app

This API is used to get the usage history of asynchronous methods (methods that respond immediately will not be included here) with chat applications (eg chat bots).

  • Endpoint
Endpoint/api/v1/user/products/{productId}/chat-app/histories
MethodGET
  • Header
NameTypeRequired
x-product-api-keyStringY
  • Path
NameTypeDescriptionRequired
productIdIntegerProduct IDY
  • Param
NameTypeDescriptionRequired
pageInteger

Page number to retrieve.If you provide invalid value the default page number will applied

Default Value: 1

N
limitInteger

Number of records per page

Default Value: 20

Max Value: 100

Note: If provided value is greater than max value, max value will be applied.

N
sessionIdStringFilter by sessionIdN
sortByStringIs one of the following values: "id", "createdAt"N
sortDirectionStringIs one of the following values: "ASC", "DESC"N
  • Response
NameTypeDescriptionRequired
codeStringError code. If code = "0", that mean successfulY
messageStringError message. If successful, the message is "success"Y
dataArray<Object>Y
> idIntegerUnique id của bản ghiY
> taskIdUUIDTask IDY
> sessionIdStringIs the session ID of the app that manages chat by sessionN
> fromStringIs one of the following values: "user", "system"Y
> dataObjectIf from is "user", this field is the data in the payload in the Use product api, otherwise if from is "system", this field is the data in the response according to the format the publisher defines in the usage tabY
> dataTypeStringIs one of the following values: "META_DATA", "S3_OBJECT", "HYBRID"N
> createdAtDate time (ISO)Time which request is createdY
metaObjectY
> itemCountIntegerThe amount of items on this specific pageY
> totalItemsIntegerThe total amount of itemsY
> itemsPerPageIntegerThe amount of items that were requested per pageY
> totalPagesIntegerThe total amount of pages in this paginatorY
> currentPageIntegerThe current page this paginator "points" toY

Example Request:

curl -X 'GET' 
'<host>/api/v1/user/products/324/chat-app/histories?page=1&limit=10' 
  -H 'accept: application/json' 
  -H 'x-product-api-key: <api_key>'

Example Response:

{
  "code": "0",
  "message": "success",
  "data": [
    {
      "id": 389,
      "taskId": "fd6db5ed-428d-4967-9aa0-cf9350330b31",
      "sessionId": "f16f1631-c540-4fec-bfda-9ea3a20a2cf9",
      "from": "system",
      "data": {
        "data": {
          "image": "",
          "answer": "Hello again! I'm Test, and I'm here to chat about travel and quality control. If you're up for it, let's chat about your bucket list destinations. What's the first place that comes to mind when you dream about your next adventure?"
        },
        "dataType": "META_DATA"
      },
      "dataType": "META_DATA",
      "createdAt": "2024-07-08T09:36:31.110Z"
    },
    {
      "id": 388,
      "taskId": "fd6db5ed-428d-4967-9aa0-cf9350330b31",
      "sessionId": "f16f1631-c540-4fec-bfda-9ea3a20a2cf9",
      "from": "user",
      "data": {
        "message": "hi",
        "sessionId": "f16f1631-c540-4fec-bfda-9ea3a20a2cf9",
        "characterId": "907f1d2f-bf96-4b8f-a77d-cdffe758749a"
      },
      "dataType": null,
      "createdAt": "2024-07-08T09:33:31.026Z"
    }
  ],
  "meta": {
    "itemsPerPage": 10,
    "totalItems": 2,
    "currentPage": 1,
    "totalPages": 1
  }
}