Emotive Auth Server API
Emotive's authentication and tenancy service — OAuth token issuance, Auth0, Google and Shopify login legs, JWT claims, brand and user management, roles, invitations, products and the Zapier app key check.
Emotive's authentication and tenancy service — OAuth token issuance, Auth0, Google and Shopify login legs, JWT claims, brand and user management, roles, invitations, products and the Zapier app key check.
components:
schemas:
Auth0JWTPayload:
properties:
access_token:
type: string
id_token:
type: string
required:
- access_token
- id_token
type: object
Auth0LoginPayload:
properties:
password:
description: password of the user for Emotive
maxLength: 100
minLength: 3
type: string
username:
description: username of the user for Emotive
maxLength: 50
minLength: 3
type: string
required:
- username
- password
type: object
Auth0PasswordResetPayload:
properties:
email:
description: email of the user for Emotive
format: email
type: string
password:
description: new password of the user for Emotive
maxLength: 100
minLength: 3
type: string
required:
- email
- password
type: object
AuthPostClientCredentialsGrantPayload:
properties:
grant_type:
description: grant type of the authentication request
enum:
- client_credentials
type: string
scope:
description: scope for the authentication request
enum:
- '*'
type: string
required:
- grant_type
type: object
AuthPostPasswordGrantPayload:
properties:
grant_type:
description: grant type of the authentication request
enum:
- password
type: string
password:
description: password of the user for Emotive
maxLength: 100
minLength: 3
type: string
refresh_token:
description: refesh token for refreshing expired access token
minLength: 10
type: string
scope:
description: scope for the authentication request
enum:
- '*'
type: string
username:
description: username of the user for Emotive
maxLength: 50
minLength: 3
type: string
required:
- username
- password
- grant_type
type: object
AuthPostRefreshGrantPayload:
properties:
grant_type:
description: grant type of the authentication request
enum:
- refresh_token
type: string
refresh_token:
description: refesh token for refreshing expired access token
minLength: 10
type: string
scope:
description: scope for the authentication request
enum:
- '*'
type: string
required:
- grant_type
type: object
AuthenticationSourceListSchema:
properties:
authentication_sources:
items:
$ref: '#/components/schemas/AuthenticationSourceSchema'
type: array
type: object
AuthenticationSourceSchema:
properties:
id:
type: integer
is_active:
type: boolean
is_default:
type: boolean
source_id:
type: integer
source_type:
enum:
- auth_password
- sensus_password
- sso
- saml
- token
type: string
type: object
BrandAPIResponse:
properties:
brands:
items:
properties:
id:
type: integer
name:
type: string
type: object
type: array
next_page:
type: string
type: object
BrandInfoAPIResponse:
properties:
company_name:
type: string
id:
type: integer
name:
type: string
status:
type: string
username:
type: string
type: object
BrandListSchema:
properties:
brands:
items:
$ref: '#/components/schemas/BrandSchema'
type: array
next_page:
type: string
type: object
BrandProducts:
properties:
description:
type: string
id:
type: integer
name:
type: string
type: object
BrandSchema:
properties:
brand_products:
items:
$ref: '#/components/schemas/BrandProducts'
type: array
id:
type: integer
name:
type: string
type: object
CreateBrandSchema:
properties:
brand_products:
items:
properties:
id:
description: Product ID
type: integer
type: object
type: array
id:
description: Sensus Brand ID
type: integer
name:
example: Brand Name
type: string
type: object
EmotivePasswordResetPayload:
properties:
password:
description: new password of the user for Emotive
maxLength: 100
minLength: 3
type: string
token:
description: unique token generated for password reset
type: string
required:
- token
- password
type: object
GroupAccessRoles:
items:
items:
enum:
- admin
- manager
- lifecycle_marketer
- support
type: string
type: array
InvitationListSchema:
properties:
invitations:
items:
$ref: '#/components/schemas/InvitationSchema'
type: array
type: object
InvitationSchema:
properties:
accepted_by:
type: integer
accepted_on:
format: date-time
type: string
created_at:
format: date-time
type: string
email:
type: string
expires_at:
format: date-time
type: string
id:
type: integer
roles:
items:
$ref: '#/components/schemas/RoleSchema'
type: array
type: object
JsonResponse:
properties:
message:
type: string
type: object
JwtClaimsResponse:
properties:
auth_type:
type: string
claims:
properties:
brand:
nullable: true
type: integer
roles:
items:
type: string
type: array
user:
type: integer
required:
- brand
- user
- roles
type: object
impersonator:
nullable: true
type: string
sub:
type: string
required:
- sub
- impersonator
- claims
- auth_type
type: object
JwtResponse:
properties:
access_token:
type: string
expires_in:
type: integer
refresh_token:
type: string
scope:
type: string
token_type:
type: string
user_info:
$ref: '#/components/schemas/UserInfo'
required:
- access_token
- expires_in
- token_type
- user_info
type: object
MutateAuthenticationSourceSchema:
properties:
authentication_details:
type: string
is_default:
type: boolean
source_id:
type: integer
type: object
MutateProductSchema:
properties:
description:
type: string
name:
type: string
roles:
items:
$ref: '#/components/schemas/RoleSchema'
type: array
type: object
MutateUserSchema:
properties:
access_roles:
description: role_ids of the user.
items:
example: 1
minimum: 1
type: integer
type: array
email:
minLength: 1
type: string
first_name:
type: string
last_name:
type: string
password:
minLength: 6
type: string
status:
enum:
- active
- suspended
- disabled
type: string
username:
minLength: 1
type: string
type: object
ProductListSchema:
properties:
products:
items:
$ref: '#/components/schemas/ProductSchema'
type: array
type: object
ProductSchema:
properties:
description:
type: string
id:
type: integer
name:
type: string
roles:
items:
$ref: '#/components/schemas/RoleSchema'
type: array
type: object
RoleSchema:
properties:
description:
type: string
id:
type: integer
name:
type: string
type: object
UserAccessRoles:
items:
properties:
brand_id:
type: integer
product_name:
type: string
role_id:
type: integer
role_name:
type: string
type: object
type: array
UserAccessSchema:
properties:
access_roles:
$ref: '#/components/schemas/UserAccessRoles'
groups:
$ref: '#/components/schemas/GroupAccessRoles'
type: object
UserInfo:
properties:
email:
type: string
first_name:
type: string
last_name:
type: string
roles:
items:
type: string
type: array
status:
type: string
username:
type: string
type: object
UserListSchema:
properties:
next_page:
format: uri
type: string
users:
items:
$ref: '#/components/schemas/UserSchema'
type: array
type: object
UserSchema:
properties:
access_roles:
$ref: '#/components/schemas/UserAccessRoles'
email:
type: string
first_name:
type: string
groups:
$ref: '#/components/schemas/GroupAccessRoles'
id:
type: integer
last_login:
format: date-time
type: string
last_name:
type: string
status:
enum:
- active
- suspended
- disabled
type: string
username:
type: string
type: object
UsersMeResponse:
properties:
brands:
items:
properties:
id:
type: integer
name:
type: string
type: object
type: array
user:
properties:
access_roles:
$ref: '#/components/schemas/UserAccessRoles'
created:
format: date-time
type: string
email:
nullable: true
type: string
email_hash:
description: HMAC-SHA256 of the user's email (or username when no email is set), signed
with the Pylon identification secret. Used to verify the user's identity to the Pylon
support chat. Null when no secret is configured.
nullable: true
type: string
first_name:
type: string
id:
type: integer
last_name:
type: string
status:
enum:
- active
- suspended
- disabled
type: string
updated:
format: date-time
nullable: true
type: string
type: object
type: object
securitySchemes:
ApiKeyAuth:
in: header
name: X-API-Key
type: apiKey
x-apikeyInfoFunc: core.api_security.api_key
info:
license:
name: Private
title: Emotive Auth Server API
version: 0.1.0
x-origin:
- url: https://api-gw.emotiveapp.co/auth/openapi.json
format: openapi
version: 3.0.2
method: searched
retrieved: '2026-08-13'
note: 'Fetched verbatim from the Emotive API gateway. Original servers[] was relative ([{"url": "/auth"}]);
resolved to the absolute gateway base for portability. Verbatim copy retained at openapi/_original/emotive-auth-openapi.json.'
openapi: 3.0.2
paths:
/auth0/google_token:
post:
operationId: controllers.auth0.issue_token_for_google_login
requestBody:
content:
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/Auth0JWTPayload'
responses:
'302':
description: Emotive admin brand selection page.
headers:
Location:
description: Emotive admin brand selection page.
schema:
format: uri
type: string
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/JsonResponse'
description: Bad Request
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/JsonResponse'
description: Authentication Failed
summary: Accept Auth0 JWT for Google login, create Emotive admin JWT, redirect to Emotive admin
brand selection page.
/auth0/login:
post:
operationId: controllers.auth0.login
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Auth0LoginPayload'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/JsonResponse'
description: Authentication Succeeded
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/JsonResponse'
description: Bad Request
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/JsonResponse'
description: Authentication Failed
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/JsonResponse'
description: Brand is not active
security:
- ApiKeyAuth: []
summary: Authenticate username/password for auth0
/auth0/password-reset:
post:
operationId: controllers.auth0.password_reset
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Auth0PasswordResetPayload'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/JsonResponse'
description: Password reset Succeeded
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/JsonResponse'
description: Bad Request (includes existing password chosen as new password)
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/JsonResponse'
description: Password reset Failed
'404':
content:
application/json:
schema:
$ref: '#/components/schemas/JsonResponse'
description: User does not exist
security:
- ApiKeyAuth: []
summary: Password reset from auth0
/auth0/token:
post:
operationId: controllers.auth0.issue_token
requestBody:
content:
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/Auth0JWTPayload'
responses:
'302':
description: Emotive home page.
headers:
Location:
description: Emotive home page.
schema:
format: uri
type: string
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/JsonResponse'
description: Bad Request
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/JsonResponse'
description: Authentication Failed
summary: Accept Auth0 JWT, create Emotive JWT, redirect to Emotive home page.
/auth0/user/{email}:
get:
operationId: controllers.auth0.get_user
parameters:
- description: email of the user for Emotive
in: path
name: email
required: true
schema:
format: email
type: string
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/JsonResponse'
description: User found
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/JsonResponse'
description: Bad Request
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/JsonResponse'
description: Authentication Failed
'404':
content:
application/json:
schema:
$ref: '#/components/schemas/JsonResponse'
description: User does not exist
security:
- ApiKeyAuth: []
summary: Get user profile info for password reset using Auth0
/google/auth:
get:
operationId: controllers.auth.google_auth
responses:
'302':
description: Redirect to Google login page.
headers:
Location:
description: Google login page.
schema:
format: uri
type: string
summary: Login with Google
/google/token:
get:
operationId: controllers.auth.google_token
responses:
'302':
description: Emotive home page.
headers:
Location:
description: Emotive home page.
schema:
format: uri
type: string
summary: Store Google Access Token and return Emotive JWT Token.
/logout:
get:
operationId: controllers.auth0.logout
responses:
'302':
description: Auth0 logout endpoint.
headers:
Location:
description: Auth0 logout endpoint.
schema:
format: uri
type: string
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/JsonResponse'
description: Authentication Failed
summary: Logout user on Emotive and redirect to Auth0 logout endpoint
/oauth/token:
post:
operationId: controllers.auth.issue_token
requestBody:
content:
application/json:
schema:
anyOf:
- $ref: '#/components/schemas/AuthPostPasswordGrantPayload'
- $ref: '#/components/schemas/AuthPostRefreshGrantPayload'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/JwtResponse'
description: Access Token info
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/JsonResponse'
description: Bad Request
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/JsonResponse'
description: Authentication Failed
summary: Get Auth Token
/shopify/auth:
get:
operationId: controllers.auth.shopify_auth
parameters:
- description: Shopfiy domain to login to.
in: query
name: shop
required: true
schema:
example: motivetesting
maxLength: 50
minLength: 3
type: string
responses:
'302':
description: Redirect to Shopify login page or Emotive login page.
headers:
Location:
description: Shopify login page. Falls back to Emotive login page if shop domain invalid.
schema:
format: uri
type: string
summary: Login with Shopify
/shopify/token:
get:
operationId: controllers.auth.shopify_token
parameters:
- description: Authorization code.
in: query
name: code
required: true
schema:
example: 027ac534b997b94ceafd4884537169be
maxLength: 50
minLength: 20
type: string
- description: hmac value of verifying request.
in: query
name: hmac
required: true
schema:
example: 70f46b9ecaa51deda7e9d87f34b3a1d5acc2ca58e637f74e267ba533caf89540
maxLength: 100
minLength: 20
type: string
- description: base64 encoded hostname.
in: query
name: host
required: true
schema:
example: bW90aXZldGVzdGluZy5teXNob3BpZnkuY29tL2FkbWlu
maxLength: 100
minLength: 10
type: string
- description: valid shop hostname.
in: query
name: shop
required: true
schema:
example: motivetesting.myshopify.com
maxLength: 64
minLength: 15
type: string
- description: Random string set in auth request.
in: query
name: state
required: true
schema:
example: d1579da7f261da46c3a52005599620
maxLength: 30
minLength: 30
type: string
- description: Unix timestamp.
in: query
name: timestamp
required: true
schema:
example: 1647991815
maxLength: 10
minLength: 10
type: integer
responses:
'302':
description: Emotive home page.
headers:
Location:
description: Emotive home page.
schema:
format: uri
type: string
summary: Store Shopify Access Token and return Emotive JWT Token.
/v1/admin/token:
get:
operationId: controllers.resource.admin_token
responses:
'302':
description: Emotive admin home page.
headers:
Location:
description: Emotive admin home page.
schema:
format: uri
type: string
summary: Sets Admin JWT cookie and redirects to Admin homepage.
/v1/brand/{brand_id}:
get:
operationId: controllers.resource.get_brand_info
parameters:
- description: id of Brand.
in: path
name: brand_id
required: true
schema:
example: 1
minimum: 1
type: integer
- description: fields to retrieve.
in: query
name: fields
schema:
default:
- id
- status
items:
enum:
- id
- status
- name
- username
- company_name
type: string
type: array
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/BrandInfoAPIResponse'
description: brand information.
'404':
description: brand_id is not valid
summary: Get Brand information for an id.
/v1/brands:
get:
operationId: controllers.resource.list_brands
parameters:
- description: last brand_id or brand_name. This will be given as part of response of API.
in: query
name: last
required: false
schema:
type: string
- description: Ordering for the results
in: query
name: order_by
required: false
schema:
default: brand_id
enum:
- brand_id
- -brand_id
- brand_name
- -brand_name
type: string
- description: number of results per API call.
in: query
name: limit
required: false
schema:
default: 20
maximum: 50
minimum: 5
type: integer
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/BrandAPIResponse'
description: List of brand ids, names.
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/JsonResponse'
description: Authentication Failed
summary: Returns paginated list of Brand names and ids.
/v1/brands/{brand_id}/invitations:
get:
operationId: controllers.resource.list_brand_invitations
parameters:
- description: id of Brand.
in: path
name: brand_id
required: true
schema:
example: 1
minimum: 1
type: integer
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/InvitationListSchema'
description: List of invitations for a brand.
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/JsonResponse'
description: Authentication Failed
'404':
description: id is not valid
summary: Returns a list of invitations for a brand.
post:
operationId: controllers.resource.create_brand_invitation
parameters:
- description: id of Brand.
in: path
name: brand_id
required: true
schema:
example: 1
minimum: 1
type: integer
requestBody:
content:
application/json:
schema:
properties:
email:
format: email
type: string
expires_at:
format: date-time
type: string
roles:
items:
example: 1
minimum: 1
type: integer
type: array
type: object
description: Create an invitation for a brand.
required: true
responses:
'201':
content:
application/json:
schema:
$ref: '#/components/schemas/InvitationSchema'
description: Invitation created for a brand.
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/JsonResponse'
description: Authentication Failed
'404':
description: id is not valid
summary: Create an invitation for a brand.
/v1/brands/{brand_id}/invitations/{invitation_id}:
delete:
operationId: controllers.resource.delete_brand_invitation
parameters:
- description: id of Brand.
in: path
name: brand_id
required: true
schema:
example: 1
minimum: 1
type: integer
- description: id of Invitation.
in: path
name: invitation_id
required: true
schema:
example: 1
minimum: 1
type: integer
responses:
'204':
description: Invitation deleted for a brand.
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/JsonResponse'
description: Authentication Failed
'404':
description: id is not valid
summary: Delete an invitation for a brand.
get:
operationId: controllers.resource.get_brand_invitation
parameters:
- description: id of Brand.
in: path
name: brand_id
required: true
schema:
example: 1
minimum: 1
type: integer
- description: id of Invitation.
in: path
name: invitation_id
required: true
schema:
example: 1
minimum: 1
type: integer
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/InvitationSchema'
description: Invitation for a brand.
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/JsonResponse'
description: Authentication Failed
'404':
description: id is not valid
summary: Returns an invitation for a brand.
/v1/brands/{brand_id}/products:
get:
operationId: controllers.brands.list_brand_products
parameters:
- description: id of Brand.
in: path
name: brand_id
required: true
schema:
example: 1
minimum: 1
type: integer
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/ProductListSchema'
description: List of products for a brand.
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/JsonResponse'
description: Authentication Failed
'404':
description: id is not valid
summary: Returns a list of products for a brand.
put:
operationId: controllers.brands.update_brand_products
parameters:
- description: id of Brand.
in: path
name: brand_id
required: true
schema:
example: 1
minimum: 1
type: integer
requestBody:
content:
application/json:
schema:
properties:
product_ids:
items:
example: 1
minimum: 1
type: integer
type: array
type: object
description: All product_ids for a brand.
required: true
x-body-name: body
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/ProductListSchema'
description: Products updated for brand.
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/JsonResponse'
description: Authentication Failed
summary: Update products for a brand.
/v1/brands/{brand_id}/users:
get:
operationId: controllers.users.list_users
parameters:
- description: id of Brand.
in: path
name: brand_id
required: true
schema:
example: 1
minimum: 1
type: integer
- description: number of results per API call.
in: query
name: limit
required: false
schema:
default: 20
maximum: 50
minimum: 5
type: integer
- description: last brand_id or brand_name. This will be given as part of response of API.
in: query
name: last
required: false
schema:
type: string
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/UserListSchema'
description: List of roles for a user in a brand.
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/JsonResponse'
description: Authentication Failed
'404':
description: id is not valid
summary: Returns paginated list of users
/v1/brands/{brand_id}/users/{user_id}/roles:
get:
operationId: controllers.resource.list_roles
parameters:
- description:
# --- truncated at 32 KB (72 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/emotive/refs/heads/main/openapi/emotive-auth-openapi.yml