Event subscription integration guide
You can integrate your own systems using event subscriptions. This lets you add custom controls and features to the image generation lifecycle.
Image generation flow
Image generation has three main stages:
Page rendering
Task submission
Task execution and result display
Event and callback flow

sdImgGenControlConfig: Displays custom text. Retrieves user information from your system using the callback request token. Displays your system information, such as user quotas.
apiAccessPreInvoke: Deducts user quotas from your system in real time.
apiAccessCommit: Maintains the status of user quota deductions in your system.
apiAccessRollback: Rolls back user quota deductions in your system.
sdTaskFinished: Stores the results of user-generated images in your system.
Callback protocol
Callback requests are POST requests sent over the HTTP protocol. The default timeout is 5 s. Ensure you respond within 5 s.
Callback types
Synchronous callback: Blocks the next step on the platform. No retries are attempted.
Asynchronous callback: Does not block the next step on the platform. If the response status code is in the 4xx or 5xx range, a retry is triggered.
Receiving callbacks
A callback request has two parts:
Request context: Includes the request initiator, target API, and event type. These details are in the URL parameters.
Request details: Contains the business parameters sent by the user to the platform. This information is in the request body, which can be empty.
Request context parameters
Name | Type | Description |
apiId | string | The user sends a request to the target API. |
bizType | string | The callback event type. |
invokeId | string | The request ID. Use this to link requests in your system. |
apiToken | string | The token used for the request (encrypted). |
sign | string | The signature. The receiver uses this to verify the authenticity of the HTTP request. |
nonce | string | A random value. The receiver uses this to verify the authenticity of the HTTP request. |
timestamp | string | The timestamp. The receiver uses this to verify the authenticity of the HTTP request. |
Responding to callbacks
Status codes
2xx: The request was successfully received and processed. The callback is complete.
4xx/5xx: The request was not successfully received or processed, and the callback failed. The platform retries the call. The retry intervals are 10 s, 30 s, 1 minute, 2 minutes, 3 minutes, 4 minutes, 5 minutes, 6 minutes, 7 minutes, 8 minutes, 9 minutes, 10 minutes, 20 minutes, 30 minutes, 1 hour, and 2 hours.
Event request parameters and response formats
apiAccessPreInvoke
After a user initiates a request, a pre-check is triggered to determine if the user has sufficient permissions.
Timing: Before the user's request is executed.
Request content: The request submitted by the user.
Request type: Synchronous.
Request format: The user's actual request content. There is no standard format.
Response body format
Name | Type | Description |
success | bool | Indicates whether the user has permission. `true` means permission is granted. |
errMessage | string | Error details. This content is displayed in a pop-up window to the customer if the pre-check fails. |
sdPreInvoke
Pre-checks an SD image generation request to determine if the user has sufficient permissions.
Timing: Before the user initiates an image generation request.
Request content: The user's original image generation request.
Request type: Synchronous.
Request details
Name | Type | Description | ||
checkpoint | object | Base model. | ||
modelId | string | Model ID. | ||
modelVersionId | string | Model version ID. | ||
aliasName | string | Alias. | ||
modelFileId | string | Model file ID. | ||
modelFileName | string | Model file name. | ||
vae | object | VAE. | ||
modelId | string | Model ID. | ||
modelVersionId | string | Model version ID. | ||
aliasName | string | Alias. | ||
modelFileId | string | Model file ID. | ||
modelFileName | string | Model file name. | ||
loras | object | LoRA. | ||
modelId | string | Model ID. | ||
modelVersionId | string | Model version ID. | ||
aliasName | string | Alias. | ||
modelFileId | string | Model file ID. | ||
modelFileName | string | Model file name. | ||
param | object | The user's actual image generation request. | ||
In SD WebUI, when a user generates a single image, this action may correspond to multiple internal text-to-image or image-to-image requests. Both sdPreInvoke and apiAccessPreInvoke are triggered before the request is executed. apiAccessPreInvoke corresponds to each sub-request that the backend receives, and its input parameter is the actual API request. sdPreInvoke corresponds to the original request that the user initiates in SD WebUI.
Response body
Name | Type | Description | ||
success | bool | Indicates whether the request was successful. `true` means success. | ||
errMessage | string | Error message. | ||
data | object | |||
info | message | string | Error message. | |
disabled | bool | The benefit check failed. | ||
sdTaskFinished
Notifies you of the image generation result after an image generation sub-task is complete.
Timing: After an image generation sub-task is complete.
Request content: The result of the user's image generation.
Request type: Asynchronous.
Request details
Name | Type | Description | |
success | bool | Indicates whether image generation was successful. `true` means success. | |
data | object | Image generation content. | |
generatedImageId | string | Image ID. | |
url | string | The URL of the image. The URL is valid for only 5 hours. Make sure to save the image elsewhere. | |
type | string | The image format, such as png. | |
modelId | string | Main model ID. | |
sdCheckpointVersionId | object | Main model version ID. | |
sdCheckpointName | string | Main model name. | |
sdVae | string | Image generation VAE. | |
sdLoras | string | LoRA used. | |
infotexts | string | Image generation parameters. | |
width | string | Image width. | |
height | object | Image height. | |
Response body
None. A successful response returns an HTTP status code of 200. If a 500 status code is returned, the system retries the call.
sdJobFinished
Notifies you of the image generation result after an image generation job is complete.
Timing: After an image generation job is complete.
Request content: The result of the user's image generation.
Request type: Asynchronous.
Request details
Name | Type | Description | |
success | bool | Indicates whether image generation was successful. `true` means success. | |
data | object | Image generation content. | |
generatedImageId | string | Image ID. | |
url | string | The URL of the image. The URL is valid for only 5 hours. Make sure to save the image elsewhere. | |
type | string | The image format, such as png. | |
modelId | string | Main model ID. | |
sdCheckpointVersionId | object | Main model version ID. | |
sdCheckpointName | string | Main model name. | |
sdVae | string | Image generation VAE. | |
sdLoras | string | LoRA used. | |
infotexts | string | Image generation parameters. | |
width | string | Image width. | |
height | object | Image height. | |
In SD WebUI, a user's request to generate an image is a job that can consist of multiple sub-tasks, such as internal text-to-image or image-to-image requests. Two events indicate completion: sdTaskFinished and sdJobFinished. The sdTaskFinished event is triggered when a single sub-task ends. The sdJobFinished event is triggered when the entire job is complete from the user's perspective. The final image that the user sees may be the result of a plugin that post-processes the outputs from multiple sub-tasks.
Response body
None. An HTTP 200 status code indicates a successful response. If an HTTP 500 status code is returned, the system retries the call.
sdImgGenControlConfig
Controls the submission block for image generation.
Timing: When a user opens the image generation page.
Request content: The current request context.
Request type: Synchronous.
Request details
Name | Type | Description | ||
checkpoint | object | Base model. | ||
modelId | string | Model ID. | ||
modelVersionId | string | Model version ID. | ||
aliasName | string | Alias. | ||
modelFileId | string | Model file ID. | ||
modelFileName | string | Model file name. | ||
vae | object | VAE. | ||
modelId | string | Model ID. | ||
modelVersionId | string | Model version ID. | ||
aliasName | string | Alias. | ||
modelFileId | string | Model file ID. | ||
modelFileName | string | Model file name. | ||
loras | object | LoRA. | ||
modelId | string | Model ID. | ||
modelVersionId | string | Model version ID. | ||
aliasName | string | Alias. | ||
modelFileId | string | Model file ID. | ||
modelFileName | string | Model file name. | ||
param | object | The user's actual image generation request. | ||
Response body
Name | Type | Description | ||
success | bool | Indicates whether the request was successful. `true` means success. | ||
errMessage | string | Error message. | ||
data | object | |||
info | message | string | The content to display below the button. | |
buttonText | string | The content to display on the button. | ||
disabled | bool | Indicates whether the image generation button is disabled. `true` means disabled. | ||
apiAccessRollback
Callback for an image generation submission failure.
Timing: When an image generation request fails to submit.
Data content: The current request context.
Request type: Synchronous.
Response body format
Name | Type | Description |
success | bool | Indicates whether the request was successful. `true` means success. |
errMessage | string | Reason for failure. |
Decrypt tokens and verify signatures (Python example)
Install dependencies
pip install pycryptodomeExample
import hmac
import hashlib
import base64
from Crypto.Hash import SHA256
from Crypto.Cipher import AES
def decrypt_api_token(
encrypted_api_token: str,
sk: str
):
"""
Decrypts the API token and returns the result.
:param encrypted_api_token:
:param sk:
:return:
"""
sha256 = SHA256.new()
sha256.update(sk.encode('utf-8'))
key = sha256.digest()[:16]
encrypted = base64.b64decode(encrypted_api_token)
iv = encrypted[:16]
cipher = AES.new(key, AES.MODE_CBC, iv)
decrypted = cipher.decrypt(encrypted[16:])
pad_size = decrypted[-1]
decrypted = decrypted[:-pad_size]
return decrypted.decode('utf-8')
def check_sign_equal(
sign: str,
ak: str,
sk: str,
nonce: str,
timestamp: str,
body: str = None,
biz_type: str = None,
api_token: str = None,
api_id: str = None,
invoke_id: str = None,
):
"""
Checks if the signature is consistent.
:param sign:
:param ak:
:param sk:
:param nonce:
:param timestamp:
:param body:
:param biz_type:
:param api_token: The decrypted token.
:param api_id:
:param invoke_id:
:return
"""
params = [ak, nonce, body, timestamp]
if biz_type and len(biz_type.strip()) > 0:
params.append(api_token)
params.append(biz_type)
params.append(api_id)
params.append(invoke_id)
sign_str = "".join(param for param in params if params is not None)
h = hmac.new(bytes(sk, 'utf-8'), bytes(sign_str, 'utf-8'), hashlib.sha256)
expect_sign = base64.b64encode(h.digest()).decode('utf-8')
return sign == expect_sign