Skip to content
SoundSyncAudio software platform

API reference

Licensing Rules, Delivery Versions and Activity API

Manage product licensing policy, versioned delivery, connection diagnostics and abandoned-checkout reminder settings.

Change licensing policy deliberately

Read licensing-rules for the assigned product, then send the full intended rule set when saving. The GET can initialize a missing rule row. PUT uses service defaults for omitted values, not sparse-patch semantics. Preserve the current fields and include expectedRules when detecting concurrent edits matters; a stale snapshot returns LICENSE_RULES_CHANGED.

Rules cover serial-only, email-entitlement or combined activation, offline-grace settings, activation limits, customer reset policy and supported invalid/refunded/suspended behavior. These configure policy; they do not establish native runtime proof for every package or grant a customer entitlement.

SoundSync

Read before editing

Inspect current product rules
curl --fail-with-body -sS "$SOUNDSYNC_API_BASE/api/developer/products/123/licensing-rules" \
  -H "Authorization: Bearer $DEVELOPER_TOKEN"

A delivery version is not an upload

Create versions with a version label, release copy, active/published flags and supported asset metadata. Use the managed upload workflow before referencing files. Creation and latest selection return the refreshed versions list. The latest action activates the selected version and removes the previous latest marker only within that product.

File keys and delivery URLs can be private. Version metadata does not validate a file, grant a download or change existing ownership. Reload the current list rather than assuming array positions or historical IDs still identify the intended release.

Connection history and online presence differ

The status endpoint selects the most recent successful connection. never_connected means no successful record was found; connected is not a real-time heartbeat or customer license proof. Use plugin-connections for diagnostic events, including event_kind, status, plugin_version, environment, failure_reason and device_hash.

Activity uses camelCase fields; connection records use database-style names. Raw bigint identifiers can be decimal strings. Preserve their exact value instead of converting them to floating-point numbers. These reports may contain customer names, email addresses and serials; keep responses private and redact screenshots.

Reminder settings do not send a campaign

Abandoned-checkout settings are developer-wide, even when an owned product is supplied as context. Delegated team calls should provide an assigned productId to select the owning developer. A save configures enabled and a delay of 1 to 168 hours; it does not guarantee delivery or bypass suppression and audience rules.

SoundSync

Continue the workflow

Private uploads

Complete uploads before saving delivery metadata.

Licensing calls

Activation, validation and deactivation.

Growth flows

Messages, audience conditions and delivery outcomes.

SoundSync

Requests and responses

GET /api/developer/products/{productId}/licensing-rules

Read or initialize product licensing rules

Auth
Account Bearer JWT
Scope
products.view and assigned-product access.
Returns
HTTP 200: rules.
Notes
This read upserts the product rule row and can initialize defaults. It is not a zero-write health check.
Request, response and error reference

No request body fields are read by this operation.

HTTP 200 response (application/json)

{
  "type": "object",
  "properties": {
    "rules": {
      "type": "object",
      "properties": {
        "id": {
          "anyOf": [
            {
              "type": "integer",
              "minimum": 1
            },
            {
              "type": "string",
              "pattern": "^[1-9][0-9]*$"
            }
          ],
          "description": "A positive identifier. PostgreSQL bigint fields can be decimal strings; preserve them without lossy numeric conversion."
        },
        "developerId": {
          "type": "integer",
          "minimum": 1
        },
        "productId": {
          "type": "integer",
          "minimum": 1
        },
        "activationMode": {
          "type": "string",
          "enum": [
            "serial_only",
            "email_entitlement",
            "serial_or_email"
          ]
        },
        "offlineGraceEnabled": {
          "type": "boolean"
        },
        "offlineGraceDays": {
          "type": "integer",
          "minimum": 0,
          "maximum": 90
        },
        "maxActivationsPerCustomer": {
          "type": [
            "integer",
            "null"
          ],
          "minimum": 1,
          "maximum": 100
        },
        "allowCustomerSelfReset": {
          "type": "boolean"
        },
        "resetCooldownDays": {
          "type": [
            "integer",
            "null"
          ],
          "minimum": 0,
          "maximum": 365
        },
        "suspendedLicenseBehavior": {
          "type": "string",
          "enum": [
            "lock",
            "warning_only",
            "grace"
          ]
        },
        "refundedOrderBehavior": {
          "type": "string",
          "enum": [
            "revoke_immediately",
            "suspend",
            "manual_review"
          ]
        },
        "failedValidationBehavior": {
          "type": "string",
          "enum": [
            "show_activation_screen",
            "show_support_message",
            "lock"
          ]
        },
        "createdAt": {
          "type": [
            "string",
            "null"
          ],
          "format": "date-time"
        },
        "updatedAt": {
          "type": [
            "string",
            "null"
          ],
          "format": "date-time"
        }
      },
      "additionalProperties": true
    }
  },
  "additionalProperties": true
}

Documented failures: 400, 401, 403, 404, 409, 500.

PUT /api/developer/products/{productId}/licensing-rules

Save licensing rules and detect stale edits

Auth
Account Bearer JWT
Scope
products.edit and assigned-product access.
Request fields
  • activationMode: serial_only | email_entitlement | serial_or_email
  • offlineGraceEnabled: boolean
  • offlineGraceDays: integer
  • maxActivationsPerCustomer: integer,null
  • allowCustomerSelfReset: boolean
  • resetCooldownDays: integer,null
  • suspendedLicenseBehavior: lock | warning_only | grace
  • refundedOrderBehavior: revoke_immediately | suspend | manual_review
  • failedValidationBehavior: show_activation_screen | show_support_message | lock
  • expectedRules: object
Returns
HTTP 200: rules.
Notes
Send the full intended rule set. Unlike a sparse PATCH, omitted fields normalize to service defaults: serial_or_email, offline grace enabled for 7 days, no explicit activation limit, self-reset off, reset cooldown 30 days, lock suspended licenses, immediate refund revocation and activation screen on failure. Snake_case field aliases are accepted. If expectedRules is supplied, include every current rule field; a mismatch returns 409 LICENSE_RULES_CHANGED. Stored rules do not prove every native runtime state has been exercised.
Request, response and error reference

Request (application/json)

{
  "type": "object",
  "properties": {
    "activationMode": {
      "type": "string",
      "enum": [
        "serial_only",
        "email_entitlement",
        "serial_or_email"
      ]
    },
    "offlineGraceEnabled": {
      "type": "boolean"
    },
    "offlineGraceDays": {
      "type": "integer",
      "minimum": 0,
      "maximum": 90
    },
    "maxActivationsPerCustomer": {
      "type": [
        "integer",
        "null"
      ],
      "minimum": 1,
      "maximum": 100
    },
    "allowCustomerSelfReset": {
      "type": "boolean"
    },
    "resetCooldownDays": {
      "type": [
        "integer",
        "null"
      ],
      "minimum": 0,
      "maximum": 365
    },
    "suspendedLicenseBehavior": {
      "type": "string",
      "enum": [
        "lock",
        "warning_only",
        "grace"
      ]
    },
    "refundedOrderBehavior": {
      "type": "string",
      "enum": [
        "revoke_immediately",
        "suspend",
        "manual_review"
      ]
    },
    "failedValidationBehavior": {
      "type": "string",
      "enum": [
        "show_activation_screen",
        "show_support_message",
        "lock"
      ]
    },
    "expectedRules": {
      "type": "object",
      "properties": {
        "activationMode": {
          "type": "string",
          "enum": [
            "serial_only",
            "email_entitlement",
            "serial_or_email"
          ]
        },
        "offlineGraceEnabled": {
          "type": "boolean"
        },
        "offlineGraceDays": {
          "type": "integer",
          "minimum": 0,
          "maximum": 90
        },
        "maxActivationsPerCustomer": {
          "type": [
            "integer",
            "null"
          ],
          "minimum": 1,
          "maximum": 100
        },
        "allowCustomerSelfReset": {
          "type": "boolean"
        },
        "resetCooldownDays": {
          "type": [
            "integer",
            "null"
          ],
          "minimum": 0,
          "maximum": 365
        },
        "suspendedLicenseBehavior": {
          "type": "string",
          "enum": [
            "lock",
            "warning_only",
            "grace"
          ]
        },
        "refundedOrderBehavior": {
          "type": "string",
          "enum": [
            "revoke_immediately",
            "suspend",
            "manual_review"
          ]
        },
        "failedValidationBehavior": {
          "type": "string",
          "enum": [
            "show_activation_screen",
            "show_support_message",
            "lock"
          ]
        }
      },
      "additionalProperties": true
    }
  },
  "additionalProperties": true
}

HTTP 200 response (application/json)

{
  "type": "object",
  "properties": {
    "rules": {
      "type": "object",
      "properties": {
        "id": {
          "anyOf": [
            {
              "type": "integer",
              "minimum": 1
            },
            {
              "type": "string",
              "pattern": "^[1-9][0-9]*$"
            }
          ],
          "description": "A positive identifier. PostgreSQL bigint fields can be decimal strings; preserve them without lossy numeric conversion."
        },
        "developerId": {
          "type": "integer",
          "minimum": 1
        },
        "productId": {
          "type": "integer",
          "minimum": 1
        },
        "activationMode": {
          "type": "string",
          "enum": [
            "serial_only",
            "email_entitlement",
            "serial_or_email"
          ]
        },
        "offlineGraceEnabled": {
          "type": "boolean"
        },
        "offlineGraceDays": {
          "type": "integer",
          "minimum": 0,
          "maximum": 90
        },
        "maxActivationsPerCustomer": {
          "type": [
            "integer",
            "null"
          ],
          "minimum": 1,
          "maximum": 100
        },
        "allowCustomerSelfReset": {
          "type": "boolean"
        },
        "resetCooldownDays": {
          "type": [
            "integer",
            "null"
          ],
          "minimum": 0,
          "maximum": 365
        },
        "suspendedLicenseBehavior": {
          "type": "string",
          "enum": [
            "lock",
            "warning_only",
            "grace"
          ]
        },
        "refundedOrderBehavior": {
          "type": "string",
          "enum": [
            "revoke_immediately",
            "suspend",
            "manual_review"
          ]
        },
        "failedValidationBehavior": {
          "type": "string",
          "enum": [
            "show_activation_screen",
            "show_support_message",
            "lock"
          ]
        },
        "createdAt": {
          "type": [
            "string",
            "null"
          ],
          "format": "date-time"
        },
        "updatedAt": {
          "type": [
            "string",
            "null"
          ],
          "format": "date-time"
        }
      },
      "additionalProperties": true
    }
  },
  "additionalProperties": true
}

Documented failures: 400, 401, 403, 404, 409, 500.

GET /api/developer/activity

Read workspace activity

Auth
Account Bearer JWT
Scope
analytics.view and all-products scope.
Request fields
  • query limit: integer
  • query eventType: string
Returns
HTTP 200: events.
Request, response and error reference

Query and header parameters

[
  {
    "name": "limit",
    "in": "query",
    "schema": {
      "type": "integer",
      "minimum": 1,
      "maximum": 100,
      "default": 25
    },
    "required": false,
    "description": ""
  },
  {
    "name": "eventType",
    "in": "query",
    "schema": {
      "type": "string"
    },
    "required": false,
    "description": ""
  }
]

No request body fields are read by this operation.

HTTP 200 response (application/json)

{
  "type": "object",
  "properties": {
    "events": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": 1
              },
              {
                "type": "string",
                "pattern": "^[1-9][0-9]*$"
              }
            ],
            "description": "A positive identifier. PostgreSQL bigint fields can be decimal strings; preserve them without lossy numeric conversion."
          },
          "developerId": {
            "type": "integer",
            "minimum": 1
          },
          "actorType": {
            "type": [
              "string",
              "null"
            ]
          },
          "actorUserId": {
            "type": [
              "integer",
              "null"
            ]
          },
          "customerId": {
            "type": [
              "integer",
              "null"
            ]
          },
          "customerEmail": {
            "type": [
              "string",
              "null"
            ]
          },
          "customerName": {
            "type": [
              "string",
              "null"
            ]
          },
          "productId": {
            "type": [
              "integer",
              "null"
            ]
          },
          "productName": {
            "type": [
              "string",
              "null"
            ]
          },
          "serialId": {
            "type": [
              "integer",
              "null"
            ]
          },
          "serialCode": {
            "type": [
              "string",
              "null"
            ]
          },
          "entitlementId": {
            "anyOf": [
              {
                "anyOf": [
                  {
                    "type": "integer",
                    "minimum": 1
                  },
                  {
                    "type": "string",
                    "pattern": "^[1-9][0-9]*$"
                  }
                ],
                "description": "A positive identifier. PostgreSQL bigint fields can be decimal strings; preserve them without lossy numeric conversion."
              },
              {
                "type": "null"
              }
            ]
          },
          "orderId": {
            "anyOf": [
              {
                "anyOf": [
                  {
                    "type": "integer",
                    "minimum": 1
                  },
                  {
                    "type": "string",
                    "pattern": "^[1-9][0-9]*$"
                  }
                ],
                "description": "A positive identifier. PostgreSQL bigint fields can be decimal strings; preserve them without lossy numeric conversion."
              },
              {
                "type": "null"
              }
            ]
          },
          "eventType": {
            "type": "string"
          },
          "severity": {
            "type": "string"
          },
          "message": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": true,
            "description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
          }
        },
        "additionalProperties": true
      }
    }
  },
  "additionalProperties": true
}

Documented failures: 400, 401, 403, 404, 409, 500.

GET /api/developer/products/{productId}/activity

Read activity for an assigned product

Auth
Account Bearer JWT
Scope
analytics.view and assigned-product access.
Request fields
  • query limit: integer
Returns
HTTP 200: events.
Notes
Also ensures the product licensing-rule row. Activity can contain customer identity and serial data; it is not public analytics.
Request, response and error reference

Query and header parameters

[
  {
    "name": "limit",
    "in": "query",
    "schema": {
      "type": "integer",
      "minimum": 1,
      "maximum": 100,
      "default": 25
    },
    "required": false,
    "description": ""
  }
]

No request body fields are read by this operation.

HTTP 200 response (application/json)

{
  "type": "object",
  "properties": {
    "events": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": 1
              },
              {
                "type": "string",
                "pattern": "^[1-9][0-9]*$"
              }
            ],
            "description": "A positive identifier. PostgreSQL bigint fields can be decimal strings; preserve them without lossy numeric conversion."
          },
          "developerId": {
            "type": "integer",
            "minimum": 1
          },
          "actorType": {
            "type": [
              "string",
              "null"
            ]
          },
          "actorUserId": {
            "type": [
              "integer",
              "null"
            ]
          },
          "customerId": {
            "type": [
              "integer",
              "null"
            ]
          },
          "customerEmail": {
            "type": [
              "string",
              "null"
            ]
          },
          "customerName": {
            "type": [
              "string",
              "null"
            ]
          },
          "productId": {
            "type": [
              "integer",
              "null"
            ]
          },
          "productName": {
            "type": [
              "string",
              "null"
            ]
          },
          "serialId": {
            "type": [
              "integer",
              "null"
            ]
          },
          "serialCode": {
            "type": [
              "string",
              "null"
            ]
          },
          "entitlementId": {
            "anyOf": [
              {
                "anyOf": [
                  {
                    "type": "integer",
                    "minimum": 1
                  },
                  {
                    "type": "string",
                    "pattern": "^[1-9][0-9]*$"
                  }
                ],
                "description": "A positive identifier. PostgreSQL bigint fields can be decimal strings; preserve them without lossy numeric conversion."
              },
              {
                "type": "null"
              }
            ]
          },
          "orderId": {
            "anyOf": [
              {
                "anyOf": [
                  {
                    "type": "integer",
                    "minimum": 1
                  },
                  {
                    "type": "string",
                    "pattern": "^[1-9][0-9]*$"
                  }
                ],
                "description": "A positive identifier. PostgreSQL bigint fields can be decimal strings; preserve them without lossy numeric conversion."
              },
              {
                "type": "null"
              }
            ]
          },
          "eventType": {
            "type": "string"
          },
          "severity": {
            "type": "string"
          },
          "message": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": true,
            "description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
          }
        },
        "additionalProperties": true
      }
    }
  },
  "additionalProperties": true
}

Documented failures: 400, 401, 403, 404, 409, 500.

GET /api/developer/products/{productId}/file-versions

List versioned delivery metadata

Auth
Account Bearer JWT
Scope
product_files.view and assigned-product access.
Returns
HTTP 200: versions.
Request, response and error reference

No request body fields are read by this operation.

HTTP 200 response (application/json)

{
  "type": "object",
  "properties": {
    "versions": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": 1
              },
              {
                "type": "string",
                "pattern": "^[1-9][0-9]*$"
              }
            ],
            "description": "A positive identifier. PostgreSQL bigint fields can be decimal strings; preserve them without lossy numeric conversion."
          },
          "productId": {
            "type": "integer",
            "minimum": 1
          },
          "version": {
            "type": "string"
          },
          "releaseTitle": {
            "type": [
              "string",
              "null"
            ]
          },
          "releaseNotes": {
            "type": [
              "string",
              "null"
            ]
          },
          "isActive": {
            "type": "boolean"
          },
          "isLatest": {
            "type": "boolean"
          },
          "published": {
            "type": "boolean"
          },
          "assets": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "anyOf": [
                    {
                      "type": "integer",
                      "minimum": 1
                    },
                    {
                      "type": "string",
                      "pattern": "^[1-9][0-9]*$"
                    }
                  ],
                  "description": "A positive identifier. PostgreSQL bigint fields can be decimal strings; preserve them without lossy numeric conversion."
                },
                "fileName": {
                  "type": "string"
                },
                "url": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "fileKey": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "fileSize": {
                  "type": [
                    "number",
                    "string",
                    "null"
                  ]
                },
                "mimeType": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "platform": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "sortOrder": {
                  "type": "integer"
                },
                "createdAt": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time"
                }
              },
              "additionalProperties": true
            }
          },
          "createdAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "updatedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        },
        "additionalProperties": true
      }
    }
  },
  "additionalProperties": true
}

Documented failures: 400, 401, 403, 404, 409, 500.

POST /api/developer/products/{productId}/file-versions

Create versioned delivery metadata

Auth
Account Bearer JWT
Scope
product_files.manage and assigned-product access.
Request fields
  • version: string (required)
  • releaseTitle: string
  • releaseNotes: string
  • isActive: boolean
  • isLatest: boolean
  • published: boolean
  • assets: array
Returns
HTTP 201: versions.
Notes
Returns the refreshed version list, not a single version. isActive and published default true; isLatest defaults false. Making a version latest clears the previous latest within this product. Asset entries are metadata, not an upload or proof that a URL is safe or publicly accessible. Use the upload workflow first and do not publish private storage keys.
Request, response and error reference

Request (application/json)

{
  "type": "object",
  "properties": {
    "version": {
      "type": "string"
    },
    "releaseTitle": {
      "type": "string"
    },
    "releaseNotes": {
      "type": "string"
    },
    "isActive": {
      "type": "boolean"
    },
    "isLatest": {
      "type": "boolean"
    },
    "published": {
      "type": "boolean"
    },
    "assets": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "fileName": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "fileKey": {
            "type": "string"
          },
          "fileSize": {
            "type": [
              "number",
              "string",
              "null"
            ]
          },
          "mimeType": {
            "type": "string"
          },
          "platform": {
            "type": "string"
          },
          "sortOrder": {
            "type": "integer"
          }
        },
        "additionalProperties": true
      }
    }
  },
  "required": [
    "version"
  ],
  "additionalProperties": true
}

HTTP 201 response (application/json)

{
  "type": "object",
  "properties": {
    "versions": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": 1
              },
              {
                "type": "string",
                "pattern": "^[1-9][0-9]*$"
              }
            ],
            "description": "A positive identifier. PostgreSQL bigint fields can be decimal strings; preserve them without lossy numeric conversion."
          },
          "productId": {
            "type": "integer",
            "minimum": 1
          },
          "version": {
            "type": "string"
          },
          "releaseTitle": {
            "type": [
              "string",
              "null"
            ]
          },
          "releaseNotes": {
            "type": [
              "string",
              "null"
            ]
          },
          "isActive": {
            "type": "boolean"
          },
          "isLatest": {
            "type": "boolean"
          },
          "published": {
            "type": "boolean"
          },
          "assets": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "anyOf": [
                    {
                      "type": "integer",
                      "minimum": 1
                    },
                    {
                      "type": "string",
                      "pattern": "^[1-9][0-9]*$"
                    }
                  ],
                  "description": "A positive identifier. PostgreSQL bigint fields can be decimal strings; preserve them without lossy numeric conversion."
                },
                "fileName": {
                  "type": "string"
                },
                "url": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "fileKey": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "fileSize": {
                  "type": [
                    "number",
                    "string",
                    "null"
                  ]
                },
                "mimeType": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "platform": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "sortOrder": {
                  "type": "integer"
                },
                "createdAt": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time"
                }
              },
              "additionalProperties": true
            }
          },
          "createdAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "updatedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        },
        "additionalProperties": true
      }
    }
  },
  "additionalProperties": true
}

Documented failures: 400, 401, 403, 404, 409, 500.

POST /api/developer/products/{productId}/file-versions/{versionId}/latest

Select the latest delivery version

Auth
Account Bearer JWT
Scope
product_files.manage and assigned-product access.
Returns
HTTP 200: versions.
Notes
The version must belong to this product/developer. Marks it active and clears other latest markers; does not upload files or change customer ownership.
Request, response and error reference

No request body fields are read by this operation.

HTTP 200 response (application/json)

{
  "type": "object",
  "properties": {
    "versions": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": 1
              },
              {
                "type": "string",
                "pattern": "^[1-9][0-9]*$"
              }
            ],
            "description": "A positive identifier. PostgreSQL bigint fields can be decimal strings; preserve them without lossy numeric conversion."
          },
          "productId": {
            "type": "integer",
            "minimum": 1
          },
          "version": {
            "type": "string"
          },
          "releaseTitle": {
            "type": [
              "string",
              "null"
            ]
          },
          "releaseNotes": {
            "type": [
              "string",
              "null"
            ]
          },
          "isActive": {
            "type": "boolean"
          },
          "isLatest": {
            "type": "boolean"
          },
          "published": {
            "type": "boolean"
          },
          "assets": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "anyOf": [
                    {
                      "type": "integer",
                      "minimum": 1
                    },
                    {
                      "type": "string",
                      "pattern": "^[1-9][0-9]*$"
                    }
                  ],
                  "description": "A positive identifier. PostgreSQL bigint fields can be decimal strings; preserve them without lossy numeric conversion."
                },
                "fileName": {
                  "type": "string"
                },
                "url": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "fileKey": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "fileSize": {
                  "type": [
                    "number",
                    "string",
                    "null"
                  ]
                },
                "mimeType": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "platform": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "sortOrder": {
                  "type": "integer"
                },
                "createdAt": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time"
                }
              },
              "additionalProperties": true
            }
          },
          "createdAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "updatedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        },
        "additionalProperties": true
      }
    }
  },
  "additionalProperties": true
}

Documented failures: 400, 401, 403, 404, 409, 500.

GET /api/developer/products/{productId}/plugin-connections

Read private product connection events

Auth
Account Bearer JWT
Scope
credentials.view and assigned-product access.
Request fields
  • query limit: integer
Returns
HTTP 200: connections.
Notes
Also ensures licensing rules. Rows use event_kind, status, plugin_version and device_hash; event_type is not the connection-event field. Customer email, serial_code and device diagnostics are private.
Request, response and error reference

Query and header parameters

[
  {
    "name": "limit",
    "in": "query",
    "schema": {
      "type": "integer",
      "minimum": 1,
      "maximum": 100,
      "default": 25
    },
    "required": false,
    "description": ""
  }
]

No request body fields are read by this operation.

HTTP 200 response (application/json)

{
  "type": "object",
  "properties": {
    "connections": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": 1
              },
              {
                "type": "string",
                "pattern": "^[1-9][0-9]*$"
              }
            ],
            "description": "A positive identifier. PostgreSQL bigint fields can be decimal strings; preserve them without lossy numeric conversion."
          },
          "developer_id": {
            "type": "integer",
            "minimum": 1
          },
          "customer_id": {
            "type": [
              "integer",
              "null"
            ]
          },
          "product_id": {
            "type": "integer",
            "minimum": 1
          },
          "serial_id": {
            "type": [
              "integer",
              "null"
            ]
          },
          "developer_customer_id": {
            "anyOf": [
              {
                "anyOf": [
                  {
                    "type": "integer",
                    "minimum": 1
                  },
                  {
                    "type": "string",
                    "pattern": "^[1-9][0-9]*$"
                  }
                ],
                "description": "A positive identifier. PostgreSQL bigint fields can be decimal strings; preserve them without lossy numeric conversion."
              },
              {
                "type": "null"
              }
            ]
          },
          "key_id": {
            "anyOf": [
              {
                "anyOf": [
                  {
                    "type": "integer",
                    "minimum": 1
                  },
                  {
                    "type": "string",
                    "pattern": "^[1-9][0-9]*$"
                  }
                ],
                "description": "A positive identifier. PostgreSQL bigint fields can be decimal strings; preserve them without lossy numeric conversion."
              },
              {
                "type": "null"
              }
            ]
          },
          "engagement_signal_id": {
            "anyOf": [
              {
                "anyOf": [
                  {
                    "type": "integer",
                    "minimum": 1
                  },
                  {
                    "type": "string",
                    "pattern": "^[1-9][0-9]*$"
                  }
                ],
                "description": "A positive identifier. PostgreSQL bigint fields can be decimal strings; preserve them without lossy numeric conversion."
              },
              {
                "type": "null"
              }
            ]
          },
          "event_kind": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "plugin_version": {
            "type": [
              "string",
              "null"
            ]
          },
          "environment": {
            "type": [
              "string",
              "null"
            ]
          },
          "device_hash": {
            "type": [
              "string",
              "null"
            ]
          },
          "failure_reason": {
            "type": [
              "string",
              "null"
            ]
          },
          "product_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "customer_email": {
            "type": [
              "string",
              "null"
            ]
          },
          "serial_code": {
            "type": [
              "string",
              "null"
            ]
          },
          "created_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": true,
            "description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
          }
        },
        "additionalProperties": true
      }
    }
  },
  "additionalProperties": true
}

Documented failures: 400, 401, 403, 404, 409, 500.

GET /api/developer/plugin-connections/products/{productId}/status

Read the most recent successful plugin connection

Auth
Account Bearer JWT
Scope
credentials.view and assigned-product access.
Returns
HTTP 200: ok, productId, connected, status, lastSeenAt, lastSuccessAt, pluginVersion, environment, credentialId, errorCode, errorReason.
Notes
Queries the latest successful connected record, not every recent failed attempt. never_connected means no successful record was found. A historical success is not proof that the plugin is online now or that a particular buyer owns a license.
Request, response and error reference

No request body fields are read by this operation.

HTTP 200 response (application/json)

{
  "type": "object",
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "productId": {
      "type": "string"
    },
    "connected": {
      "type": "boolean"
    },
    "status": {
      "type": "string"
    },
    "lastSeenAt": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    },
    "lastSuccessAt": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    },
    "pluginVersion": {
      "type": [
        "string",
        "null"
      ]
    },
    "environment": {
      "type": [
        "string",
        "null"
      ]
    },
    "credentialId": {
      "type": [
        "string",
        "null"
      ]
    },
    "errorCode": {
      "type": [
        "string",
        "null"
      ]
    },
    "errorReason": {
      "type": [
        "string",
        "null"
      ]
    }
  },
  "additionalProperties": true
}

Documented failures: 400, 401, 403, 404, 409, 500.

GET /api/developer/abandoned-checkout-settings

Read abandoned-checkout reminder settings

Auth
Account Bearer JWT
Scope
marketing.view and all-products scope. Product context must belong to the effective developer.
Request fields
  • query productId: integer
Returns
HTTP 200: settings.
Notes
These are developer-wide settings, not separate policies per product. Product context resolves the owning developer; delegated calls should supply an assigned productId. PUT defaults delayHours to 24 and accepts delay_hours. Saving does not send a message or bypass audience eligibility and suppression.
Request, response and error reference

Query and header parameters

[
  {
    "name": "productId",
    "in": "query",
    "schema": {
      "type": "integer",
      "minimum": 1
    },
    "required": false,
    "description": ""
  }
]

No request body fields are read by this operation.

HTTP 200 response (application/json)

{
  "type": "object",
  "properties": {
    "settings": {
      "type": "object",
      "properties": {
        "enabled": {
          "type": "boolean"
        },
        "delayHours": {
          "type": "integer",
          "minimum": 1,
          "maximum": 168
        }
      },
      "additionalProperties": true
    }
  },
  "additionalProperties": true
}

Documented failures: 400, 401, 403, 404, 409, 500.

PUT /api/developer/abandoned-checkout-settings

Save abandoned-checkout reminder settings

Auth
Account Bearer JWT
Scope
marketing.manage and all-products scope. Product context must belong to the effective developer.
Request fields
  • query productId: integer
  • enabled: boolean
  • delayHours: integer
  • productId: integer
Returns
HTTP 200: settings.
Notes
These are developer-wide settings, not separate policies per product. Product context resolves the owning developer; delegated calls should supply an assigned productId. PUT defaults delayHours to 24 and accepts delay_hours. Saving does not send a message or bypass audience eligibility and suppression.
Request, response and error reference

Query and header parameters

[
  {
    "name": "productId",
    "in": "query",
    "schema": {
      "type": "integer",
      "minimum": 1
    },
    "required": false,
    "description": ""
  }
]

Request (application/json)

{
  "type": "object",
  "properties": {
    "enabled": {
      "type": "boolean"
    },
    "delayHours": {
      "type": "integer",
      "minimum": 1,
      "maximum": 168
    },
    "productId": {
      "type": "integer",
      "minimum": 1
    }
  },
  "additionalProperties": true
}

HTTP 200 response (application/json)

{
  "type": "object",
  "properties": {
    "settings": {
      "type": "object",
      "properties": {
        "enabled": {
          "type": "boolean"
        },
        "delayHours": {
          "type": "integer",
          "minimum": 1,
          "maximum": 168
        }
      },
      "additionalProperties": true
    }
  },
  "additionalProperties": true
}

Documented failures: 400, 401, 403, 404, 409, 500.