Skip to main content

Members

Base URL: https://app.neuroflash.com/api/workspace-service

Manage workspace membership and roles.

Create a workspace member

POST/v1/workspaces/{workspaceId}/workspace-members

Creates a new workspace member. Only workspace owners and admins can create members.

Path Parameters

ParameterTypeRequiredDescription
workspaceIdstringYesWorkspace ID

Request Body

FieldTypeRequiredDescription
legacyCustomerIdintegerNoID of the legacy customer
rolestringYesRole of the member in the workspace

Response

FieldTypeDescription
_embeddedobject
customerobject
emailstringEmail of the customer
hadTrialbooleanTrue if the customer has ever started a trial in any workspace
legacyIdintegerID of the customer in the legacy system
namestringName of the customer
permissionsobject
workspaceobject
_embeddedobject
avatarobject
_embeddedobject
signedUrlstring
createdAtstring
createdByUserIdstring
fileNamestring
idstring
signedUrlstring
storageKeystring
updatedAtstring
workspaceIdstring
billingContactobject
activeDiscountstringreadonly synced from stripe: true if a discount is active for this stripe customer
addressLine1stringreadonly synced from stripe: First line of the address of the billing contact
addressLine2stringreadonly synced from stripe: Second line of the address of the billing contact
citystringreadonly synced from stripe: City of the billing contact
countrystringreadonly synced from stripe: Country of the billing contact
createdAtstring
createdByUserIdstring
defaultPaymentCardNumberLastFourDigitsstring
defaultPaymentMethodstring
defaultPaymentMethodCardBrandstring
emailstringEmail address of the billing contact
idstring
importedFromLegacyCustomerIdintegerDeprecated: only needed while import from legacy api is still active ID of the legacy customer this was imported from
namestringName of the billing contact
postalCodestringreadonly synced from stripe: Postal code of the billing contact
statestringreadonly synced from stripe: State of the billing contact
stripeCustomerIdstringStripe customer ID for billing purposes. Could become optional if we add other payment providers
updatedAtstring
currentSubscriptionobject
_embeddedobject
availableWordsintegerdeprecated: remove once the frontend doesn't need it anymore deprecated, moved to rootLevel
newPricingPlanobject
activebooleanset to true when this pricingPlan can be configured on existing and new subscriptions
billingIntervalstring
categoryIdstringID of the category this plan belongs to
displayNamestringname used for internal purposes like the admin-ui or hubspot. Should not be displayed to customers
idstringid of the pricing plan
importedFromLegacyIdinteger
isDefaultbooleanIs this the default plan for new customers?
priceInEuronumberhow much the customer needs to pay for this subscription
pricePerCurrencyobjectA map of string keys to float values
stripeBillingPortalEnabledbooleantrue if subscriptions with this pricingPlan can be self-managed in the stripe billing portal
stripePriceIdstringID of the price in stripe
stripeTrackUsagebooleanwhen true then the usage for subscriptions with this pricingPlan should be tracked in stripe
tierinteger
trialDaysintegerhow many trial days are allowed for this plan
pricingPlanobject
activebooleanset to true when this pricingPlan can be configured on existing and new subscriptions
billingIntervalstring
categoryIdstringID of the category this plan belongs to
displayNamestringname used for internal purposes like the admin-ui or hubspot. Should not be displayed to customers
idstringid of the pricing plan
importedFromLegacyIdinteger
isDefaultbooleanIs this the default plan for new customers?
priceInEuronumberhow much the customer needs to pay for this subscription
pricePerCurrencyobjectA map of string keys to float values
stripeBillingPortalEnabledbooleantrue if subscriptions with this pricingPlan can be self-managed in the stripe billing portal
stripePriceIdstringID of the price in stripe
stripeTrackUsagebooleanwhen true then the usage for subscriptions with this pricingPlan should be tracked in stripe
tierinteger
trialDaysintegerhow many trial days are allowed for this plan
pricingPlanCategoryobject
displayNamestring
idstring
translationKeystring
activebooleanFlag indicating whether the subscription is active. Subscriptions can become inactive if they are paused or have more members than the current plan allows
activeDiscountsarray<string>readonly synced from stripe: true if a discount is active for this stripe subscription
availableWordsintegernumber of words that can still be used in this workspace in the current billing period.
bonusWordsintegerdeprecated: will be moved to a separate limits table/service. Can currently be managed by admins Additional bonus words available for use
createdAtstring
createdByUserIdstring
currencystring
endDatestringreadonly synced from Stripe: date at which this subscription will automatically be cancelled
idstring
importedFromLegacyCustomerIdintegerDeprecated: only needed while import from legacy api is still active ID of the legacy customer this was imported from
isGracePeriodbooleantrue if the subscription will be cancelled at a set date in the future
isTrialbooleantrue if this is currently a trial period
limitRenewalDatestringnext date on which the limits (like words available, images available etc) will be reset. This happens every month, starting with the start of the subscription
nextSubscriptionCycleStartstringreadonly synced from Stripe: Timestamp when the next billing cycle starts. This is NOT necessarily the timestamp when we reset the limits in our system because we reset them monthly even if this is a yearly plan
paymentCardNumberLastFourDigitsstringreadonly synced from Stripe: Last four digits of the payment card number. Uses the default payment on the subscription with a fallback to the payment from the last invoice
paymentMethodCardBrandstring
paymentPausedbooleanreadonly synced from Stripe: true if the payment collection for this subscription is currently paused. Even though stripe intends these subscription to stay active and just be free for a while, we treat subscriptions with payment paused as inactive
paymentTypestring
pricingPlanIdstring
pricingPlanWordsintegerdeprecated: these fields are managed internally but will be moved to the limit structure deprecated: will be moved to a separate limits table/service how many words the pricingPlan from this subscription allows.
sepaPaymentFailedbooleanreadonly synced from Stripe: Flag indicating whether the SEPA payment has failed
spilloverWordsintegerdeprecated: will be moved to a separate limits table/service. Used to calculate the available words next month because you can only keep overspilled words from last month, not accumulate them over multiple months Words carried over from previous month
stripeStatusstring
stripeSubscriptionIdstringStripe subscription ID
stripeSubscriptionItemIdstringID of the subscription item in stripe (subscriptions should only have one item)
trialEndsAtstringreadonly synced from Stripe: Timestamp when the trial period ends
trialStartedAtstringreadonly synced from stripe: if a trial is in progress, date when it started
updatedAtstring
usedWordsintegerdeprecated: will be moved to a separate limits table/service How many words were used in this workspace in the current month
workspaceIdstringID of the workspace this subscription belongs to
billingContactIdstringID of the billing contact for this workspace
createdAtstring
createdByUserIdstring
currentSubscriptionIdstringID of the current subscription for this workspace
firstMemberInvitedAtstringdeprecated Timestamp when the first member was invited to the workspace
firstPaidSubscriptionAtstringIf this workspace ever had a paid subscription, this contains the date at which the first one started
idstring
importedFromLegacyCustomerIdintegerdeprecated Some customers don't have an assigned team in the legacy system as owner but they still need a workspace to which we can import the subscription
importedFromLegacyTeamIdintegerdeprecated: fields that are currently still needed for the legacy system ID of the legacy team this workspace was imported from
keystringHuman readable unique identifier of the workspace
keyIndexintegerUnique auto generated index which is used to generate a unique key
namestringName of the workspace
trialStartedAtstringIf this workspace ever had a subscription with a trial this contains the time when it was started
updatedAtstring
createdAtstring
createdByUserIdstring
idstring
importedFromLegacyCustomerIdintegerdeprecated some customers don't have an assigned team in the legacy system as owner but they still need a workspace to which we can import the subscription.
importedFromLegacyTeamCustomerIdintegerdeprecated: for legacy import ID of the legacy team customer this was imported from
legacyCustomerIdintegerID of the legacy customer
rolestringRole of the member in the workspace
updatedAtstring
userIdstringID of the user
workspaceIdstringID of the workspace the member belongs to

Example

curl -X POST "https://app.neuroflash.com/api/workspace-service/v1/workspaces/{workspace_id}/workspace-members" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"legacyCustomerId": 0,
"role": "string"
}'

Response:

{
"_embedded": {
"customer": {
"email": "eren.jaeger@neuroflash.com",
"hadTrial": false,
"legacyId": 5,
"name": "Eren Jaeger"
},
"permissions": {},
"workspace": {
"_embedded": {
"avatar": {
"_embedded": "...",
"createdAt": "...",
"createdByUserId": "...",
"fileName": "...",
"id": "...",
"signedUrl": "...",
"storageKey": "...",
"updatedAt": "...",
"workspaceId": "..."
},
"billingContact": {
"activeDiscount": "...",
"addressLine1": "...",
"addressLine2": "...",
"city": "...",
"country": "...",
"createdAt": "...",
"createdByUserId": "...",
"defaultPaymentCardNumberLastFourDigits": "...",
"defaultPaymentMethod": "...",
"defaultPaymentMethodCardBrand": "...",
"email": "...",
"id": "...",
"importedFromLegacyCustomerId": "...",
"name": "...",
"postalCode": "...",
"state": "...",
"stripeCustomerId": "...",
"updatedAt": "..."
},
"currentSubscription": {
"_embedded": "...",
"active": "...",
"activeDiscounts": "...",
"availableWords": "...",
"bonusWords": "...",
"createdAt": "...",
"createdByUserId": "...",
"currency": "...",
"endDate": "...",
"id": "...",
"importedFromLegacyCustomerId": "...",
"isGracePeriod": "...",
"isTrial": "...",
"limitRenewalDate": "...",
"nextSubscriptionCycleStart": "...",
"paymentCardNumberLastFourDigits": "...",
"paymentMethodCardBrand": "...",
"paymentPaused": "...",
"paymentType": "...",
"pricingPlanId": "...",
"pricingPlanWords": "...",
"sepaPaymentFailed": "...",
"spilloverWords": "...",
"stripeStatus": "...",
"stripeSubscriptionId": "...",
"stripeSubscriptionItemId": "...",
"trialEndsAt": "...",
"trialStartedAt": "...",
"updatedAt": "...",
"usedWords": "...",
"workspaceId": "..."
}
},
"billingContactId": "550e8400-e29b-41d4-a716-446655440000",
"createdAt": "2025-01-14T16:20:59Z",
"createdByUserId": "b0920767-2e30-48d3-80ce-268810bc433a",
"currentSubscriptionId": "550e8400-e29b-41d4-a716-446655440000",
"firstMemberInvitedAt": "2022-01-01T00:00:00Z",
"firstPaidSubscriptionAt": "string",
"id": "113c0b32-ed6c-4421-b7da-d1faf238eb56",
"importedFromLegacyCustomerId": 177,
"importedFromLegacyTeamId": 187,
"key": "NF-GK352",
"keyIndex": 57,
"name": "Online Marketing Team",
"trialStartedAt": "2014-01-02T14:22:00Z",
"updatedAt": "2025-01-14T16:20:59Z"
}
},
"createdAt": "2025-01-14T16:20:59Z",
"createdByUserId": "b0920767-2e30-48d3-80ce-268810bc433a",
"id": "113c0b32-ed6c-4421-b7da-d1faf238eb56",
"importedFromLegacyCustomerId": 177,
"importedFromLegacyTeamCustomerId": 12345,
"legacyCustomerId": 5,
"role": "MEMBER",
"updatedAt": "2025-01-14T16:20:59Z",
"userId": "3445546543",
"workspaceId": "992fd647-d15c-40e9-b61c-e19ef9eea35e"
}

list workspaces-members of the given workspace

GET/v1/workspaces/{workspaceId}/workspace-members

Path Parameters

ParameterTypeRequiredDescription
workspaceIdstringYesworkspaceId

Query Parameters

ParameterTypeDefaultDescription
rolestringfilter by member role
legacyCustomerIdsarrayFilter by owner legacy customer ids

Response

FieldTypeDescription
dataarray<object>
_embeddedobject
customerobject
emailstringEmail of the customer
hadTrialbooleanTrue if the customer has ever started a trial in any workspace
legacyIdintegerID of the customer in the legacy system
namestringName of the customer
permissionsobject
workspaceobject
_embeddedobject
avatarobject
_embeddedobject
signedUrlstring
createdAtstring
createdByUserIdstring
fileNamestring
idstring
signedUrlstring
storageKeystring
updatedAtstring
workspaceIdstring
billingContactobject
activeDiscountstringreadonly synced from stripe: true if a discount is active for this stripe customer
addressLine1stringreadonly synced from stripe: First line of the address of the billing contact
addressLine2stringreadonly synced from stripe: Second line of the address of the billing contact
citystringreadonly synced from stripe: City of the billing contact
countrystringreadonly synced from stripe: Country of the billing contact
createdAtstring
createdByUserIdstring
defaultPaymentCardNumberLastFourDigitsstring
defaultPaymentMethodstring
defaultPaymentMethodCardBrandstring
emailstringEmail address of the billing contact
idstring
importedFromLegacyCustomerIdintegerDeprecated: only needed while import from legacy api is still active ID of the legacy customer this was imported from
namestringName of the billing contact
postalCodestringreadonly synced from stripe: Postal code of the billing contact
statestringreadonly synced from stripe: State of the billing contact
stripeCustomerIdstringStripe customer ID for billing purposes. Could become optional if we add other payment providers
updatedAtstring
currentSubscriptionobject
_embeddedobject
availableWordsintegerdeprecated: remove once the frontend doesn't need it anymore deprecated, moved to rootLevel
newPricingPlanobject
activebooleanset to true when this pricingPlan can be configured on existing and new subscriptions
billingIntervalstring
categoryIdstringID of the category this plan belongs to
displayNamestringname used for internal purposes like the admin-ui or hubspot. Should not be displayed to customers
idstringid of the pricing plan
importedFromLegacyIdinteger
isDefaultbooleanIs this the default plan for new customers?
priceInEuronumberhow much the customer needs to pay for this subscription
pricePerCurrencyobjectA map of string keys to float values
stripeBillingPortalEnabledbooleantrue if subscriptions with this pricingPlan can be self-managed in the stripe billing portal
stripePriceIdstringID of the price in stripe
stripeTrackUsagebooleanwhen true then the usage for subscriptions with this pricingPlan should be tracked in stripe
tierinteger
trialDaysintegerhow many trial days are allowed for this plan
pricingPlanobject
activebooleanset to true when this pricingPlan can be configured on existing and new subscriptions
billingIntervalstring
categoryIdstringID of the category this plan belongs to
displayNamestringname used for internal purposes like the admin-ui or hubspot. Should not be displayed to customers
idstringid of the pricing plan
importedFromLegacyIdinteger
isDefaultbooleanIs this the default plan for new customers?
priceInEuronumberhow much the customer needs to pay for this subscription
pricePerCurrencyobjectA map of string keys to float values
stripeBillingPortalEnabledbooleantrue if subscriptions with this pricingPlan can be self-managed in the stripe billing portal
stripePriceIdstringID of the price in stripe
stripeTrackUsagebooleanwhen true then the usage for subscriptions with this pricingPlan should be tracked in stripe
tierinteger
trialDaysintegerhow many trial days are allowed for this plan
pricingPlanCategoryobject
displayNamestring
idstring
translationKeystring
activebooleanFlag indicating whether the subscription is active. Subscriptions can become inactive if they are paused or have more members than the current plan allows
activeDiscountsarray<string>readonly synced from stripe: true if a discount is active for this stripe subscription
availableWordsintegernumber of words that can still be used in this workspace in the current billing period.
bonusWordsintegerdeprecated: will be moved to a separate limits table/service. Can currently be managed by admins Additional bonus words available for use
createdAtstring
createdByUserIdstring
currencystring
endDatestringreadonly synced from Stripe: date at which this subscription will automatically be cancelled
idstring
importedFromLegacyCustomerIdintegerDeprecated: only needed while import from legacy api is still active ID of the legacy customer this was imported from
isGracePeriodbooleantrue if the subscription will be cancelled at a set date in the future
isTrialbooleantrue if this is currently a trial period
limitRenewalDatestringnext date on which the limits (like words available, images available etc) will be reset. This happens every month, starting with the start of the subscription
nextSubscriptionCycleStartstringreadonly synced from Stripe: Timestamp when the next billing cycle starts. This is NOT necessarily the timestamp when we reset the limits in our system because we reset them monthly even if this is a yearly plan
paymentCardNumberLastFourDigitsstringreadonly synced from Stripe: Last four digits of the payment card number. Uses the default payment on the subscription with a fallback to the payment from the last invoice
paymentMethodCardBrandstring
paymentPausedbooleanreadonly synced from Stripe: true if the payment collection for this subscription is currently paused. Even though stripe intends these subscription to stay active and just be free for a while, we treat subscriptions with payment paused as inactive
paymentTypestring
pricingPlanIdstring
pricingPlanWordsintegerdeprecated: these fields are managed internally but will be moved to the limit structure deprecated: will be moved to a separate limits table/service how many words the pricingPlan from this subscription allows.
sepaPaymentFailedbooleanreadonly synced from Stripe: Flag indicating whether the SEPA payment has failed
spilloverWordsintegerdeprecated: will be moved to a separate limits table/service. Used to calculate the available words next month because you can only keep overspilled words from last month, not accumulate them over multiple months Words carried over from previous month
stripeStatusstring
stripeSubscriptionIdstringStripe subscription ID
stripeSubscriptionItemIdstringID of the subscription item in stripe (subscriptions should only have one item)
trialEndsAtstringreadonly synced from Stripe: Timestamp when the trial period ends
trialStartedAtstringreadonly synced from stripe: if a trial is in progress, date when it started
updatedAtstring
usedWordsintegerdeprecated: will be moved to a separate limits table/service How many words were used in this workspace in the current month
workspaceIdstringID of the workspace this subscription belongs to
billingContactIdstringID of the billing contact for this workspace
createdAtstring
createdByUserIdstring
currentSubscriptionIdstringID of the current subscription for this workspace
firstMemberInvitedAtstringdeprecated Timestamp when the first member was invited to the workspace
firstPaidSubscriptionAtstringIf this workspace ever had a paid subscription, this contains the date at which the first one started
idstring
importedFromLegacyCustomerIdintegerdeprecated Some customers don't have an assigned team in the legacy system as owner but they still need a workspace to which we can import the subscription
importedFromLegacyTeamIdintegerdeprecated: fields that are currently still needed for the legacy system ID of the legacy team this workspace was imported from
keystringHuman readable unique identifier of the workspace
keyIndexintegerUnique auto generated index which is used to generate a unique key
namestringName of the workspace
trialStartedAtstringIf this workspace ever had a subscription with a trial this contains the time when it was started
updatedAtstring
createdAtstring
createdByUserIdstring
idstring
importedFromLegacyCustomerIdintegerdeprecated some customers don't have an assigned team in the legacy system as owner but they still need a workspace to which we can import the subscription.
importedFromLegacyTeamCustomerIdintegerdeprecated: for legacy import ID of the legacy team customer this was imported from
legacyCustomerIdintegerID of the legacy customer
rolestringRole of the member in the workspace
updatedAtstring
userIdstringID of the user
workspaceIdstringID of the workspace the member belongs to
pageobject
currentPageinteger
sizeinteger
totalElementsinteger
totalPagesinteger

Example

curl "https://app.neuroflash.com/api/workspace-service/v1/workspaces/{workspace_id}/workspace-members" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Response:

{
"data": [
{
"_embedded": {
"customer": {
"email": "...",
"hadTrial": "...",
"legacyId": "...",
"name": "..."
},
"permissions": {},
"workspace": {
"_embedded": "...",
"billingContactId": "...",
"createdAt": "...",
"createdByUserId": "...",
"currentSubscriptionId": "...",
"firstMemberInvitedAt": "...",
"firstPaidSubscriptionAt": "...",
"id": "...",
"importedFromLegacyCustomerId": "...",
"importedFromLegacyTeamId": "...",
"key": "...",
"keyIndex": "...",
"name": "...",
"trialStartedAt": "...",
"updatedAt": "..."
}
},
"createdAt": "2025-01-14T16:20:59Z",
"createdByUserId": "b0920767-2e30-48d3-80ce-268810bc433a",
"id": "113c0b32-ed6c-4421-b7da-d1faf238eb56",
"importedFromLegacyCustomerId": 177,
"importedFromLegacyTeamCustomerId": 12345,
"legacyCustomerId": 5,
"role": "MEMBER",
"updatedAt": "2025-01-14T16:20:59Z",
"userId": "3445546543",
"workspaceId": "992fd647-d15c-40e9-b61c-e19ef9eea35e"
}
],
"page": {
"currentPage": 2,
"size": 10,
"totalElements": 35,
"totalPages": 4
}
}

get a workspace member

GET/v1/workspaces/{workspaceId}/workspace-members/{memberId}

Path Parameters

ParameterTypeRequiredDescription
workspaceIdstringYesWorkspace ID
memberIdstringYesMember ID

Response

FieldTypeDescription
_embeddedobject
customerobject
emailstringEmail of the customer
hadTrialbooleanTrue if the customer has ever started a trial in any workspace
legacyIdintegerID of the customer in the legacy system
namestringName of the customer
permissionsobject
workspaceobject
_embeddedobject
avatarobject
_embeddedobject
signedUrlstring
createdAtstring
createdByUserIdstring
fileNamestring
idstring
signedUrlstring
storageKeystring
updatedAtstring
workspaceIdstring
billingContactobject
activeDiscountstringreadonly synced from stripe: true if a discount is active for this stripe customer
addressLine1stringreadonly synced from stripe: First line of the address of the billing contact
addressLine2stringreadonly synced from stripe: Second line of the address of the billing contact
citystringreadonly synced from stripe: City of the billing contact
countrystringreadonly synced from stripe: Country of the billing contact
createdAtstring
createdByUserIdstring
defaultPaymentCardNumberLastFourDigitsstring
defaultPaymentMethodstring
defaultPaymentMethodCardBrandstring
emailstringEmail address of the billing contact
idstring
importedFromLegacyCustomerIdintegerDeprecated: only needed while import from legacy api is still active ID of the legacy customer this was imported from
namestringName of the billing contact
postalCodestringreadonly synced from stripe: Postal code of the billing contact
statestringreadonly synced from stripe: State of the billing contact
stripeCustomerIdstringStripe customer ID for billing purposes. Could become optional if we add other payment providers
updatedAtstring
currentSubscriptionobject
_embeddedobject
availableWordsintegerdeprecated: remove once the frontend doesn't need it anymore deprecated, moved to rootLevel
newPricingPlanobject
activebooleanset to true when this pricingPlan can be configured on existing and new subscriptions
billingIntervalstring
categoryIdstringID of the category this plan belongs to
displayNamestringname used for internal purposes like the admin-ui or hubspot. Should not be displayed to customers
idstringid of the pricing plan
importedFromLegacyIdinteger
isDefaultbooleanIs this the default plan for new customers?
priceInEuronumberhow much the customer needs to pay for this subscription
pricePerCurrencyobjectA map of string keys to float values
stripeBillingPortalEnabledbooleantrue if subscriptions with this pricingPlan can be self-managed in the stripe billing portal
stripePriceIdstringID of the price in stripe
stripeTrackUsagebooleanwhen true then the usage for subscriptions with this pricingPlan should be tracked in stripe
tierinteger
trialDaysintegerhow many trial days are allowed for this plan
pricingPlanobject
activebooleanset to true when this pricingPlan can be configured on existing and new subscriptions
billingIntervalstring
categoryIdstringID of the category this plan belongs to
displayNamestringname used for internal purposes like the admin-ui or hubspot. Should not be displayed to customers
idstringid of the pricing plan
importedFromLegacyIdinteger
isDefaultbooleanIs this the default plan for new customers?
priceInEuronumberhow much the customer needs to pay for this subscription
pricePerCurrencyobjectA map of string keys to float values
stripeBillingPortalEnabledbooleantrue if subscriptions with this pricingPlan can be self-managed in the stripe billing portal
stripePriceIdstringID of the price in stripe
stripeTrackUsagebooleanwhen true then the usage for subscriptions with this pricingPlan should be tracked in stripe
tierinteger
trialDaysintegerhow many trial days are allowed for this plan
pricingPlanCategoryobject
displayNamestring
idstring
translationKeystring
activebooleanFlag indicating whether the subscription is active. Subscriptions can become inactive if they are paused or have more members than the current plan allows
activeDiscountsarray<string>readonly synced from stripe: true if a discount is active for this stripe subscription
availableWordsintegernumber of words that can still be used in this workspace in the current billing period.
bonusWordsintegerdeprecated: will be moved to a separate limits table/service. Can currently be managed by admins Additional bonus words available for use
createdAtstring
createdByUserIdstring
currencystring
endDatestringreadonly synced from Stripe: date at which this subscription will automatically be cancelled
idstring
importedFromLegacyCustomerIdintegerDeprecated: only needed while import from legacy api is still active ID of the legacy customer this was imported from
isGracePeriodbooleantrue if the subscription will be cancelled at a set date in the future
isTrialbooleantrue if this is currently a trial period
limitRenewalDatestringnext date on which the limits (like words available, images available etc) will be reset. This happens every month, starting with the start of the subscription
nextSubscriptionCycleStartstringreadonly synced from Stripe: Timestamp when the next billing cycle starts. This is NOT necessarily the timestamp when we reset the limits in our system because we reset them monthly even if this is a yearly plan
paymentCardNumberLastFourDigitsstringreadonly synced from Stripe: Last four digits of the payment card number. Uses the default payment on the subscription with a fallback to the payment from the last invoice
paymentMethodCardBrandstring
paymentPausedbooleanreadonly synced from Stripe: true if the payment collection for this subscription is currently paused. Even though stripe intends these subscription to stay active and just be free for a while, we treat subscriptions with payment paused as inactive
paymentTypestring
pricingPlanIdstring
pricingPlanWordsintegerdeprecated: these fields are managed internally but will be moved to the limit structure deprecated: will be moved to a separate limits table/service how many words the pricingPlan from this subscription allows.
sepaPaymentFailedbooleanreadonly synced from Stripe: Flag indicating whether the SEPA payment has failed
spilloverWordsintegerdeprecated: will be moved to a separate limits table/service. Used to calculate the available words next month because you can only keep overspilled words from last month, not accumulate them over multiple months Words carried over from previous month
stripeStatusstring
stripeSubscriptionIdstringStripe subscription ID
stripeSubscriptionItemIdstringID of the subscription item in stripe (subscriptions should only have one item)
trialEndsAtstringreadonly synced from Stripe: Timestamp when the trial period ends
trialStartedAtstringreadonly synced from stripe: if a trial is in progress, date when it started
updatedAtstring
usedWordsintegerdeprecated: will be moved to a separate limits table/service How many words were used in this workspace in the current month
workspaceIdstringID of the workspace this subscription belongs to
billingContactIdstringID of the billing contact for this workspace
createdAtstring
createdByUserIdstring
currentSubscriptionIdstringID of the current subscription for this workspace
firstMemberInvitedAtstringdeprecated Timestamp when the first member was invited to the workspace
firstPaidSubscriptionAtstringIf this workspace ever had a paid subscription, this contains the date at which the first one started
idstring
importedFromLegacyCustomerIdintegerdeprecated Some customers don't have an assigned team in the legacy system as owner but they still need a workspace to which we can import the subscription
importedFromLegacyTeamIdintegerdeprecated: fields that are currently still needed for the legacy system ID of the legacy team this workspace was imported from
keystringHuman readable unique identifier of the workspace
keyIndexintegerUnique auto generated index which is used to generate a unique key
namestringName of the workspace
trialStartedAtstringIf this workspace ever had a subscription with a trial this contains the time when it was started
updatedAtstring
createdAtstring
createdByUserIdstring
idstring
importedFromLegacyCustomerIdintegerdeprecated some customers don't have an assigned team in the legacy system as owner but they still need a workspace to which we can import the subscription.
importedFromLegacyTeamCustomerIdintegerdeprecated: for legacy import ID of the legacy team customer this was imported from
legacyCustomerIdintegerID of the legacy customer
rolestringRole of the member in the workspace
updatedAtstring
userIdstringID of the user
workspaceIdstringID of the workspace the member belongs to

Example

curl "https://app.neuroflash.com/api/workspace-service/v1/workspaces/{workspace_id}/workspace-members/{member_id}" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Response:

{
"_embedded": {
"customer": {
"email": "eren.jaeger@neuroflash.com",
"hadTrial": false,
"legacyId": 5,
"name": "Eren Jaeger"
},
"permissions": {},
"workspace": {
"_embedded": {
"avatar": {
"_embedded": "...",
"createdAt": "...",
"createdByUserId": "...",
"fileName": "...",
"id": "...",
"signedUrl": "...",
"storageKey": "...",
"updatedAt": "...",
"workspaceId": "..."
},
"billingContact": {
"activeDiscount": "...",
"addressLine1": "...",
"addressLine2": "...",
"city": "...",
"country": "...",
"createdAt": "...",
"createdByUserId": "...",
"defaultPaymentCardNumberLastFourDigits": "...",
"defaultPaymentMethod": "...",
"defaultPaymentMethodCardBrand": "...",
"email": "...",
"id": "...",
"importedFromLegacyCustomerId": "...",
"name": "...",
"postalCode": "...",
"state": "...",
"stripeCustomerId": "...",
"updatedAt": "..."
},
"currentSubscription": {
"_embedded": "...",
"active": "...",
"activeDiscounts": "...",
"availableWords": "...",
"bonusWords": "...",
"createdAt": "...",
"createdByUserId": "...",
"currency": "...",
"endDate": "...",
"id": "...",
"importedFromLegacyCustomerId": "...",
"isGracePeriod": "...",
"isTrial": "...",
"limitRenewalDate": "...",
"nextSubscriptionCycleStart": "...",
"paymentCardNumberLastFourDigits": "...",
"paymentMethodCardBrand": "...",
"paymentPaused": "...",
"paymentType": "...",
"pricingPlanId": "...",
"pricingPlanWords": "...",
"sepaPaymentFailed": "...",
"spilloverWords": "...",
"stripeStatus": "...",
"stripeSubscriptionId": "...",
"stripeSubscriptionItemId": "...",
"trialEndsAt": "...",
"trialStartedAt": "...",
"updatedAt": "...",
"usedWords": "...",
"workspaceId": "..."
}
},
"billingContactId": "550e8400-e29b-41d4-a716-446655440000",
"createdAt": "2025-01-14T16:20:59Z",
"createdByUserId": "b0920767-2e30-48d3-80ce-268810bc433a",
"currentSubscriptionId": "550e8400-e29b-41d4-a716-446655440000",
"firstMemberInvitedAt": "2022-01-01T00:00:00Z",
"firstPaidSubscriptionAt": "string",
"id": "113c0b32-ed6c-4421-b7da-d1faf238eb56",
"importedFromLegacyCustomerId": 177,
"importedFromLegacyTeamId": 187,
"key": "NF-GK352",
"keyIndex": 57,
"name": "Online Marketing Team",
"trialStartedAt": "2014-01-02T14:22:00Z",
"updatedAt": "2025-01-14T16:20:59Z"
}
},
"createdAt": "2025-01-14T16:20:59Z",
"createdByUserId": "b0920767-2e30-48d3-80ce-268810bc433a",
"id": "113c0b32-ed6c-4421-b7da-d1faf238eb56",
"importedFromLegacyCustomerId": 177,
"importedFromLegacyTeamCustomerId": 12345,
"legacyCustomerId": 5,
"role": "MEMBER",
"updatedAt": "2025-01-14T16:20:59Z",
"userId": "3445546543",
"workspaceId": "992fd647-d15c-40e9-b61c-e19ef9eea35e"
}

Update a workspace member

PUT/v1/workspaces/{workspaceId}/workspace-members/{memberId}

Updates a workspace member's role. Every workspace must have at least one owner.

Path Parameters

ParameterTypeRequiredDescription
workspaceIdstringYesWorkspace ID
memberIdstringYesMember ID

Request Body

FieldTypeRequiredDescription
rolestringYesRole of the member in the workspace

Response

FieldTypeDescription
_embeddedobject
customerobject
emailstringEmail of the customer
hadTrialbooleanTrue if the customer has ever started a trial in any workspace
legacyIdintegerID of the customer in the legacy system
namestringName of the customer
permissionsobject
workspaceobject
_embeddedobject
avatarobject
_embeddedobject
signedUrlstring
createdAtstring
createdByUserIdstring
fileNamestring
idstring
signedUrlstring
storageKeystring
updatedAtstring
workspaceIdstring
billingContactobject
activeDiscountstringreadonly synced from stripe: true if a discount is active for this stripe customer
addressLine1stringreadonly synced from stripe: First line of the address of the billing contact
addressLine2stringreadonly synced from stripe: Second line of the address of the billing contact
citystringreadonly synced from stripe: City of the billing contact
countrystringreadonly synced from stripe: Country of the billing contact
createdAtstring
createdByUserIdstring
defaultPaymentCardNumberLastFourDigitsstring
defaultPaymentMethodstring
defaultPaymentMethodCardBrandstring
emailstringEmail address of the billing contact
idstring
importedFromLegacyCustomerIdintegerDeprecated: only needed while import from legacy api is still active ID of the legacy customer this was imported from
namestringName of the billing contact
postalCodestringreadonly synced from stripe: Postal code of the billing contact
statestringreadonly synced from stripe: State of the billing contact
stripeCustomerIdstringStripe customer ID for billing purposes. Could become optional if we add other payment providers
updatedAtstring
currentSubscriptionobject
_embeddedobject
availableWordsintegerdeprecated: remove once the frontend doesn't need it anymore deprecated, moved to rootLevel
newPricingPlanobject
activebooleanset to true when this pricingPlan can be configured on existing and new subscriptions
billingIntervalstring
categoryIdstringID of the category this plan belongs to
displayNamestringname used for internal purposes like the admin-ui or hubspot. Should not be displayed to customers
idstringid of the pricing plan
importedFromLegacyIdinteger
isDefaultbooleanIs this the default plan for new customers?
priceInEuronumberhow much the customer needs to pay for this subscription
pricePerCurrencyobjectA map of string keys to float values
stripeBillingPortalEnabledbooleantrue if subscriptions with this pricingPlan can be self-managed in the stripe billing portal
stripePriceIdstringID of the price in stripe
stripeTrackUsagebooleanwhen true then the usage for subscriptions with this pricingPlan should be tracked in stripe
tierinteger
trialDaysintegerhow many trial days are allowed for this plan
pricingPlanobject
activebooleanset to true when this pricingPlan can be configured on existing and new subscriptions
billingIntervalstring
categoryIdstringID of the category this plan belongs to
displayNamestringname used for internal purposes like the admin-ui or hubspot. Should not be displayed to customers
idstringid of the pricing plan
importedFromLegacyIdinteger
isDefaultbooleanIs this the default plan for new customers?
priceInEuronumberhow much the customer needs to pay for this subscription
pricePerCurrencyobjectA map of string keys to float values
stripeBillingPortalEnabledbooleantrue if subscriptions with this pricingPlan can be self-managed in the stripe billing portal
stripePriceIdstringID of the price in stripe
stripeTrackUsagebooleanwhen true then the usage for subscriptions with this pricingPlan should be tracked in stripe
tierinteger
trialDaysintegerhow many trial days are allowed for this plan
pricingPlanCategoryobject
displayNamestring
idstring
translationKeystring
activebooleanFlag indicating whether the subscription is active. Subscriptions can become inactive if they are paused or have more members than the current plan allows
activeDiscountsarray<string>readonly synced from stripe: true if a discount is active for this stripe subscription
availableWordsintegernumber of words that can still be used in this workspace in the current billing period.
bonusWordsintegerdeprecated: will be moved to a separate limits table/service. Can currently be managed by admins Additional bonus words available for use
createdAtstring
createdByUserIdstring
currencystring
endDatestringreadonly synced from Stripe: date at which this subscription will automatically be cancelled
idstring
importedFromLegacyCustomerIdintegerDeprecated: only needed while import from legacy api is still active ID of the legacy customer this was imported from
isGracePeriodbooleantrue if the subscription will be cancelled at a set date in the future
isTrialbooleantrue if this is currently a trial period
limitRenewalDatestringnext date on which the limits (like words available, images available etc) will be reset. This happens every month, starting with the start of the subscription
nextSubscriptionCycleStartstringreadonly synced from Stripe: Timestamp when the next billing cycle starts. This is NOT necessarily the timestamp when we reset the limits in our system because we reset them monthly even if this is a yearly plan
paymentCardNumberLastFourDigitsstringreadonly synced from Stripe: Last four digits of the payment card number. Uses the default payment on the subscription with a fallback to the payment from the last invoice
paymentMethodCardBrandstring
paymentPausedbooleanreadonly synced from Stripe: true if the payment collection for this subscription is currently paused. Even though stripe intends these subscription to stay active and just be free for a while, we treat subscriptions with payment paused as inactive
paymentTypestring
pricingPlanIdstring
pricingPlanWordsintegerdeprecated: these fields are managed internally but will be moved to the limit structure deprecated: will be moved to a separate limits table/service how many words the pricingPlan from this subscription allows.
sepaPaymentFailedbooleanreadonly synced from Stripe: Flag indicating whether the SEPA payment has failed
spilloverWordsintegerdeprecated: will be moved to a separate limits table/service. Used to calculate the available words next month because you can only keep overspilled words from last month, not accumulate them over multiple months Words carried over from previous month
stripeStatusstring
stripeSubscriptionIdstringStripe subscription ID
stripeSubscriptionItemIdstringID of the subscription item in stripe (subscriptions should only have one item)
trialEndsAtstringreadonly synced from Stripe: Timestamp when the trial period ends
trialStartedAtstringreadonly synced from stripe: if a trial is in progress, date when it started
updatedAtstring
usedWordsintegerdeprecated: will be moved to a separate limits table/service How many words were used in this workspace in the current month
workspaceIdstringID of the workspace this subscription belongs to
billingContactIdstringID of the billing contact for this workspace
createdAtstring
createdByUserIdstring
currentSubscriptionIdstringID of the current subscription for this workspace
firstMemberInvitedAtstringdeprecated Timestamp when the first member was invited to the workspace
firstPaidSubscriptionAtstringIf this workspace ever had a paid subscription, this contains the date at which the first one started
idstring
importedFromLegacyCustomerIdintegerdeprecated Some customers don't have an assigned team in the legacy system as owner but they still need a workspace to which we can import the subscription
importedFromLegacyTeamIdintegerdeprecated: fields that are currently still needed for the legacy system ID of the legacy team this workspace was imported from
keystringHuman readable unique identifier of the workspace
keyIndexintegerUnique auto generated index which is used to generate a unique key
namestringName of the workspace
trialStartedAtstringIf this workspace ever had a subscription with a trial this contains the time when it was started
updatedAtstring
createdAtstring
createdByUserIdstring
idstring
importedFromLegacyCustomerIdintegerdeprecated some customers don't have an assigned team in the legacy system as owner but they still need a workspace to which we can import the subscription.
importedFromLegacyTeamCustomerIdintegerdeprecated: for legacy import ID of the legacy team customer this was imported from
legacyCustomerIdintegerID of the legacy customer
rolestringRole of the member in the workspace
updatedAtstring
userIdstringID of the user
workspaceIdstringID of the workspace the member belongs to

Example

curl -X PUT "https://app.neuroflash.com/api/workspace-service/v1/workspaces/{workspace_id}/workspace-members/{member_id}" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"role": "string"
}'

Response:

{
"_embedded": {
"customer": {
"email": "eren.jaeger@neuroflash.com",
"hadTrial": false,
"legacyId": 5,
"name": "Eren Jaeger"
},
"permissions": {},
"workspace": {
"_embedded": {
"avatar": {
"_embedded": "...",
"createdAt": "...",
"createdByUserId": "...",
"fileName": "...",
"id": "...",
"signedUrl": "...",
"storageKey": "...",
"updatedAt": "...",
"workspaceId": "..."
},
"billingContact": {
"activeDiscount": "...",
"addressLine1": "...",
"addressLine2": "...",
"city": "...",
"country": "...",
"createdAt": "...",
"createdByUserId": "...",
"defaultPaymentCardNumberLastFourDigits": "...",
"defaultPaymentMethod": "...",
"defaultPaymentMethodCardBrand": "...",
"email": "...",
"id": "...",
"importedFromLegacyCustomerId": "...",
"name": "...",
"postalCode": "...",
"state": "...",
"stripeCustomerId": "...",
"updatedAt": "..."
},
"currentSubscription": {
"_embedded": "...",
"active": "...",
"activeDiscounts": "...",
"availableWords": "...",
"bonusWords": "...",
"createdAt": "...",
"createdByUserId": "...",
"currency": "...",
"endDate": "...",
"id": "...",
"importedFromLegacyCustomerId": "...",
"isGracePeriod": "...",
"isTrial": "...",
"limitRenewalDate": "...",
"nextSubscriptionCycleStart": "...",
"paymentCardNumberLastFourDigits": "...",
"paymentMethodCardBrand": "...",
"paymentPaused": "...",
"paymentType": "...",
"pricingPlanId": "...",
"pricingPlanWords": "...",
"sepaPaymentFailed": "...",
"spilloverWords": "...",
"stripeStatus": "...",
"stripeSubscriptionId": "...",
"stripeSubscriptionItemId": "...",
"trialEndsAt": "...",
"trialStartedAt": "...",
"updatedAt": "...",
"usedWords": "...",
"workspaceId": "..."
}
},
"billingContactId": "550e8400-e29b-41d4-a716-446655440000",
"createdAt": "2025-01-14T16:20:59Z",
"createdByUserId": "b0920767-2e30-48d3-80ce-268810bc433a",
"currentSubscriptionId": "550e8400-e29b-41d4-a716-446655440000",
"firstMemberInvitedAt": "2022-01-01T00:00:00Z",
"firstPaidSubscriptionAt": "string",
"id": "113c0b32-ed6c-4421-b7da-d1faf238eb56",
"importedFromLegacyCustomerId": 177,
"importedFromLegacyTeamId": 187,
"key": "NF-GK352",
"keyIndex": 57,
"name": "Online Marketing Team",
"trialStartedAt": "2014-01-02T14:22:00Z",
"updatedAt": "2025-01-14T16:20:59Z"
}
},
"createdAt": "2025-01-14T16:20:59Z",
"createdByUserId": "b0920767-2e30-48d3-80ce-268810bc433a",
"id": "113c0b32-ed6c-4421-b7da-d1faf238eb56",
"importedFromLegacyCustomerId": 177,
"importedFromLegacyTeamCustomerId": 12345,
"legacyCustomerId": 5,
"role": "MEMBER",
"updatedAt": "2025-01-14T16:20:59Z",
"userId": "3445546543",
"workspaceId": "992fd647-d15c-40e9-b61c-e19ef9eea35e"
}

Delete a workspace member

DELETE/v1/workspaces/{workspaceId}/workspace-members/{memberId}

Deletes a workspace member. The last owner of a workspace cannot be deleted

Path Parameters

ParameterTypeRequiredDescription
workspaceIdstringYesWorkspace ID
memberIdstringYesMember ID

Example

curl -X DELETE "https://app.neuroflash.com/api/workspace-service/v1/workspaces/{workspace_id}/workspace-members/{member_id}" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

list workspaces-members of the given customer

GET/v1/customers/{customerId}/workspace-members

Path Parameters

ParameterTypeRequiredDescription
customerIdstringYescustomerId

Query Parameters

ParameterTypeDefaultDescription
pageintegerPage number for pagination
sizeintegerNumber of items per page
orderstringOrder direction: asc or desc
sortstringField name to sort by
rolestringfilter by member role
legacyCustomerIdsarrayFilter by owner legacy customer ids

Response

FieldTypeDescription
dataarray<object>
_embeddedobject
customerobject
emailstringEmail of the customer
hadTrialbooleanTrue if the customer has ever started a trial in any workspace
legacyIdintegerID of the customer in the legacy system
namestringName of the customer
permissionsobject
workspaceobject
_embeddedobject
avatarobject
_embeddedobject
signedUrlstring
createdAtstring
createdByUserIdstring
fileNamestring
idstring
signedUrlstring
storageKeystring
updatedAtstring
workspaceIdstring
billingContactobject
activeDiscountstringreadonly synced from stripe: true if a discount is active for this stripe customer
addressLine1stringreadonly synced from stripe: First line of the address of the billing contact
addressLine2stringreadonly synced from stripe: Second line of the address of the billing contact
citystringreadonly synced from stripe: City of the billing contact
countrystringreadonly synced from stripe: Country of the billing contact
createdAtstring
createdByUserIdstring
defaultPaymentCardNumberLastFourDigitsstring
defaultPaymentMethodstring
defaultPaymentMethodCardBrandstring
emailstringEmail address of the billing contact
idstring
importedFromLegacyCustomerIdintegerDeprecated: only needed while import from legacy api is still active ID of the legacy customer this was imported from
namestringName of the billing contact
postalCodestringreadonly synced from stripe: Postal code of the billing contact
statestringreadonly synced from stripe: State of the billing contact
stripeCustomerIdstringStripe customer ID for billing purposes. Could become optional if we add other payment providers
updatedAtstring
currentSubscriptionobject
_embeddedobject
availableWordsintegerdeprecated: remove once the frontend doesn't need it anymore deprecated, moved to rootLevel
newPricingPlanobject
activebooleanset to true when this pricingPlan can be configured on existing and new subscriptions
billingIntervalstring
categoryIdstringID of the category this plan belongs to
displayNamestringname used for internal purposes like the admin-ui or hubspot. Should not be displayed to customers
idstringid of the pricing plan
importedFromLegacyIdinteger
isDefaultbooleanIs this the default plan for new customers?
priceInEuronumberhow much the customer needs to pay for this subscription
pricePerCurrencyobjectA map of string keys to float values
stripeBillingPortalEnabledbooleantrue if subscriptions with this pricingPlan can be self-managed in the stripe billing portal
stripePriceIdstringID of the price in stripe
stripeTrackUsagebooleanwhen true then the usage for subscriptions with this pricingPlan should be tracked in stripe
tierinteger
trialDaysintegerhow many trial days are allowed for this plan
pricingPlanobject
activebooleanset to true when this pricingPlan can be configured on existing and new subscriptions
billingIntervalstring
categoryIdstringID of the category this plan belongs to
displayNamestringname used for internal purposes like the admin-ui or hubspot. Should not be displayed to customers
idstringid of the pricing plan
importedFromLegacyIdinteger
isDefaultbooleanIs this the default plan for new customers?
priceInEuronumberhow much the customer needs to pay for this subscription
pricePerCurrencyobjectA map of string keys to float values
stripeBillingPortalEnabledbooleantrue if subscriptions with this pricingPlan can be self-managed in the stripe billing portal
stripePriceIdstringID of the price in stripe
stripeTrackUsagebooleanwhen true then the usage for subscriptions with this pricingPlan should be tracked in stripe
tierinteger
trialDaysintegerhow many trial days are allowed for this plan
pricingPlanCategoryobject
displayNamestring
idstring
translationKeystring
activebooleanFlag indicating whether the subscription is active. Subscriptions can become inactive if they are paused or have more members than the current plan allows
activeDiscountsarray<string>readonly synced from stripe: true if a discount is active for this stripe subscription
availableWordsintegernumber of words that can still be used in this workspace in the current billing period.
bonusWordsintegerdeprecated: will be moved to a separate limits table/service. Can currently be managed by admins Additional bonus words available for use
createdAtstring
createdByUserIdstring
currencystring
endDatestringreadonly synced from Stripe: date at which this subscription will automatically be cancelled
idstring
importedFromLegacyCustomerIdintegerDeprecated: only needed while import from legacy api is still active ID of the legacy customer this was imported from
isGracePeriodbooleantrue if the subscription will be cancelled at a set date in the future
isTrialbooleantrue if this is currently a trial period
limitRenewalDatestringnext date on which the limits (like words available, images available etc) will be reset. This happens every month, starting with the start of the subscription
nextSubscriptionCycleStartstringreadonly synced from Stripe: Timestamp when the next billing cycle starts. This is NOT necessarily the timestamp when we reset the limits in our system because we reset them monthly even if this is a yearly plan
paymentCardNumberLastFourDigitsstringreadonly synced from Stripe: Last four digits of the payment card number. Uses the default payment on the subscription with a fallback to the payment from the last invoice
paymentMethodCardBrandstring
paymentPausedbooleanreadonly synced from Stripe: true if the payment collection for this subscription is currently paused. Even though stripe intends these subscription to stay active and just be free for a while, we treat subscriptions with payment paused as inactive
paymentTypestring
pricingPlanIdstring
pricingPlanWordsintegerdeprecated: these fields are managed internally but will be moved to the limit structure deprecated: will be moved to a separate limits table/service how many words the pricingPlan from this subscription allows.
sepaPaymentFailedbooleanreadonly synced from Stripe: Flag indicating whether the SEPA payment has failed
spilloverWordsintegerdeprecated: will be moved to a separate limits table/service. Used to calculate the available words next month because you can only keep overspilled words from last month, not accumulate them over multiple months Words carried over from previous month
stripeStatusstring
stripeSubscriptionIdstringStripe subscription ID
stripeSubscriptionItemIdstringID of the subscription item in stripe (subscriptions should only have one item)
trialEndsAtstringreadonly synced from Stripe: Timestamp when the trial period ends
trialStartedAtstringreadonly synced from stripe: if a trial is in progress, date when it started
updatedAtstring
usedWordsintegerdeprecated: will be moved to a separate limits table/service How many words were used in this workspace in the current month
workspaceIdstringID of the workspace this subscription belongs to
billingContactIdstringID of the billing contact for this workspace
createdAtstring
createdByUserIdstring
currentSubscriptionIdstringID of the current subscription for this workspace
firstMemberInvitedAtstringdeprecated Timestamp when the first member was invited to the workspace
firstPaidSubscriptionAtstringIf this workspace ever had a paid subscription, this contains the date at which the first one started
idstring
importedFromLegacyCustomerIdintegerdeprecated Some customers don't have an assigned team in the legacy system as owner but they still need a workspace to which we can import the subscription
importedFromLegacyTeamIdintegerdeprecated: fields that are currently still needed for the legacy system ID of the legacy team this workspace was imported from
keystringHuman readable unique identifier of the workspace
keyIndexintegerUnique auto generated index which is used to generate a unique key
namestringName of the workspace
trialStartedAtstringIf this workspace ever had a subscription with a trial this contains the time when it was started
updatedAtstring
createdAtstring
createdByUserIdstring
idstring
importedFromLegacyCustomerIdintegerdeprecated some customers don't have an assigned team in the legacy system as owner but they still need a workspace to which we can import the subscription.
importedFromLegacyTeamCustomerIdintegerdeprecated: for legacy import ID of the legacy team customer this was imported from
legacyCustomerIdintegerID of the legacy customer
rolestringRole of the member in the workspace
updatedAtstring
userIdstringID of the user
workspaceIdstringID of the workspace the member belongs to
pageobject
currentPageinteger
sizeinteger
totalElementsinteger
totalPagesinteger

Example

curl "https://app.neuroflash.com/api/workspace-service/v1/customers/{customer_id}/workspace-members" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Response:

{
"data": [
{
"_embedded": {
"customer": {
"email": "...",
"hadTrial": "...",
"legacyId": "...",
"name": "..."
},
"permissions": {},
"workspace": {
"_embedded": "...",
"billingContactId": "...",
"createdAt": "...",
"createdByUserId": "...",
"currentSubscriptionId": "...",
"firstMemberInvitedAt": "...",
"firstPaidSubscriptionAt": "...",
"id": "...",
"importedFromLegacyCustomerId": "...",
"importedFromLegacyTeamId": "...",
"key": "...",
"keyIndex": "...",
"name": "...",
"trialStartedAt": "...",
"updatedAt": "..."
}
},
"createdAt": "2025-01-14T16:20:59Z",
"createdByUserId": "b0920767-2e30-48d3-80ce-268810bc433a",
"id": "113c0b32-ed6c-4421-b7da-d1faf238eb56",
"importedFromLegacyCustomerId": 177,
"importedFromLegacyTeamCustomerId": 12345,
"legacyCustomerId": 5,
"role": "MEMBER",
"updatedAt": "2025-01-14T16:20:59Z",
"userId": "3445546543",
"workspaceId": "992fd647-d15c-40e9-b61c-e19ef9eea35e"
}
],
"page": {
"currentPage": 2,
"size": 10,
"totalElements": 35,
"totalPages": 4
}
}

list workspaces-members of the given user

GET/v1/users/{userId}/workspace-members

Path Parameters

ParameterTypeRequiredDescription
userIdstringYesuserId

Query Parameters

ParameterTypeDefaultDescription
pageintegerPage number for pagination
sizeintegerNumber of items per page
orderstringOrder direction: asc or desc
sortstringField name to sort by
rolestringfilter by member role
legacyCustomerIdsarrayFilter by owner legacy customer ids

Response

FieldTypeDescription
dataarray<object>
_embeddedobject
customerobject
emailstringEmail of the customer
hadTrialbooleanTrue if the customer has ever started a trial in any workspace
legacyIdintegerID of the customer in the legacy system
namestringName of the customer
permissionsobject
workspaceobject
_embeddedobject
avatarobject
_embeddedobject
signedUrlstring
createdAtstring
createdByUserIdstring
fileNamestring
idstring
signedUrlstring
storageKeystring
updatedAtstring
workspaceIdstring
billingContactobject
activeDiscountstringreadonly synced from stripe: true if a discount is active for this stripe customer
addressLine1stringreadonly synced from stripe: First line of the address of the billing contact
addressLine2stringreadonly synced from stripe: Second line of the address of the billing contact
citystringreadonly synced from stripe: City of the billing contact
countrystringreadonly synced from stripe: Country of the billing contact
createdAtstring
createdByUserIdstring
defaultPaymentCardNumberLastFourDigitsstring
defaultPaymentMethodstring
defaultPaymentMethodCardBrandstring
emailstringEmail address of the billing contact
idstring
importedFromLegacyCustomerIdintegerDeprecated: only needed while import from legacy api is still active ID of the legacy customer this was imported from
namestringName of the billing contact
postalCodestringreadonly synced from stripe: Postal code of the billing contact
statestringreadonly synced from stripe: State of the billing contact
stripeCustomerIdstringStripe customer ID for billing purposes. Could become optional if we add other payment providers
updatedAtstring
currentSubscriptionobject
_embeddedobject
availableWordsintegerdeprecated: remove once the frontend doesn't need it anymore deprecated, moved to rootLevel
newPricingPlanobject
activebooleanset to true when this pricingPlan can be configured on existing and new subscriptions
billingIntervalstring
categoryIdstringID of the category this plan belongs to
displayNamestringname used for internal purposes like the admin-ui or hubspot. Should not be displayed to customers
idstringid of the pricing plan
importedFromLegacyIdinteger
isDefaultbooleanIs this the default plan for new customers?
priceInEuronumberhow much the customer needs to pay for this subscription
pricePerCurrencyobjectA map of string keys to float values
stripeBillingPortalEnabledbooleantrue if subscriptions with this pricingPlan can be self-managed in the stripe billing portal
stripePriceIdstringID of the price in stripe
stripeTrackUsagebooleanwhen true then the usage for subscriptions with this pricingPlan should be tracked in stripe
tierinteger
trialDaysintegerhow many trial days are allowed for this plan
pricingPlanobject
activebooleanset to true when this pricingPlan can be configured on existing and new subscriptions
billingIntervalstring
categoryIdstringID of the category this plan belongs to
displayNamestringname used for internal purposes like the admin-ui or hubspot. Should not be displayed to customers
idstringid of the pricing plan
importedFromLegacyIdinteger
isDefaultbooleanIs this the default plan for new customers?
priceInEuronumberhow much the customer needs to pay for this subscription
pricePerCurrencyobjectA map of string keys to float values
stripeBillingPortalEnabledbooleantrue if subscriptions with this pricingPlan can be self-managed in the stripe billing portal
stripePriceIdstringID of the price in stripe
stripeTrackUsagebooleanwhen true then the usage for subscriptions with this pricingPlan should be tracked in stripe
tierinteger
trialDaysintegerhow many trial days are allowed for this plan
pricingPlanCategoryobject
displayNamestring
idstring
translationKeystring
activebooleanFlag indicating whether the subscription is active. Subscriptions can become inactive if they are paused or have more members than the current plan allows
activeDiscountsarray<string>readonly synced from stripe: true if a discount is active for this stripe subscription
availableWordsintegernumber of words that can still be used in this workspace in the current billing period.
bonusWordsintegerdeprecated: will be moved to a separate limits table/service. Can currently be managed by admins Additional bonus words available for use
createdAtstring
createdByUserIdstring
currencystring
endDatestringreadonly synced from Stripe: date at which this subscription will automatically be cancelled
idstring
importedFromLegacyCustomerIdintegerDeprecated: only needed while import from legacy api is still active ID of the legacy customer this was imported from
isGracePeriodbooleantrue if the subscription will be cancelled at a set date in the future
isTrialbooleantrue if this is currently a trial period
limitRenewalDatestringnext date on which the limits (like words available, images available etc) will be reset. This happens every month, starting with the start of the subscription
nextSubscriptionCycleStartstringreadonly synced from Stripe: Timestamp when the next billing cycle starts. This is NOT necessarily the timestamp when we reset the limits in our system because we reset them monthly even if this is a yearly plan
paymentCardNumberLastFourDigitsstringreadonly synced from Stripe: Last four digits of the payment card number. Uses the default payment on the subscription with a fallback to the payment from the last invoice
paymentMethodCardBrandstring
paymentPausedbooleanreadonly synced from Stripe: true if the payment collection for this subscription is currently paused. Even though stripe intends these subscription to stay active and just be free for a while, we treat subscriptions with payment paused as inactive
paymentTypestring
pricingPlanIdstring
pricingPlanWordsintegerdeprecated: these fields are managed internally but will be moved to the limit structure deprecated: will be moved to a separate limits table/service how many words the pricingPlan from this subscription allows.
sepaPaymentFailedbooleanreadonly synced from Stripe: Flag indicating whether the SEPA payment has failed
spilloverWordsintegerdeprecated: will be moved to a separate limits table/service. Used to calculate the available words next month because you can only keep overspilled words from last month, not accumulate them over multiple months Words carried over from previous month
stripeStatusstring
stripeSubscriptionIdstringStripe subscription ID
stripeSubscriptionItemIdstringID of the subscription item in stripe (subscriptions should only have one item)
trialEndsAtstringreadonly synced from Stripe: Timestamp when the trial period ends
trialStartedAtstringreadonly synced from stripe: if a trial is in progress, date when it started
updatedAtstring
usedWordsintegerdeprecated: will be moved to a separate limits table/service How many words were used in this workspace in the current month
workspaceIdstringID of the workspace this subscription belongs to
billingContactIdstringID of the billing contact for this workspace
createdAtstring
createdByUserIdstring
currentSubscriptionIdstringID of the current subscription for this workspace
firstMemberInvitedAtstringdeprecated Timestamp when the first member was invited to the workspace
firstPaidSubscriptionAtstringIf this workspace ever had a paid subscription, this contains the date at which the first one started
idstring
importedFromLegacyCustomerIdintegerdeprecated Some customers don't have an assigned team in the legacy system as owner but they still need a workspace to which we can import the subscription
importedFromLegacyTeamIdintegerdeprecated: fields that are currently still needed for the legacy system ID of the legacy team this workspace was imported from
keystringHuman readable unique identifier of the workspace
keyIndexintegerUnique auto generated index which is used to generate a unique key
namestringName of the workspace
trialStartedAtstringIf this workspace ever had a subscription with a trial this contains the time when it was started
updatedAtstring
createdAtstring
createdByUserIdstring
idstring
importedFromLegacyCustomerIdintegerdeprecated some customers don't have an assigned team in the legacy system as owner but they still need a workspace to which we can import the subscription.
importedFromLegacyTeamCustomerIdintegerdeprecated: for legacy import ID of the legacy team customer this was imported from
legacyCustomerIdintegerID of the legacy customer
rolestringRole of the member in the workspace
updatedAtstring
userIdstringID of the user
workspaceIdstringID of the workspace the member belongs to
pageobject
currentPageinteger
sizeinteger
totalElementsinteger
totalPagesinteger

Example

curl "https://app.neuroflash.com/api/workspace-service/v1/users/{user_id}/workspace-members" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Response:

{
"data": [
{
"_embedded": {
"customer": {
"email": "...",
"hadTrial": "...",
"legacyId": "...",
"name": "..."
},
"permissions": {},
"workspace": {
"_embedded": "...",
"billingContactId": "...",
"createdAt": "...",
"createdByUserId": "...",
"currentSubscriptionId": "...",
"firstMemberInvitedAt": "...",
"firstPaidSubscriptionAt": "...",
"id": "...",
"importedFromLegacyCustomerId": "...",
"importedFromLegacyTeamId": "...",
"key": "...",
"keyIndex": "...",
"name": "...",
"trialStartedAt": "...",
"updatedAt": "..."
}
},
"createdAt": "2025-01-14T16:20:59Z",
"createdByUserId": "b0920767-2e30-48d3-80ce-268810bc433a",
"id": "113c0b32-ed6c-4421-b7da-d1faf238eb56",
"importedFromLegacyCustomerId": 177,
"importedFromLegacyTeamCustomerId": 12345,
"legacyCustomerId": 5,
"role": "MEMBER",
"updatedAt": "2025-01-14T16:20:59Z",
"userId": "3445546543",
"workspaceId": "992fd647-d15c-40e9-b61c-e19ef9eea35e"
}
],
"page": {
"currentPage": 2,
"size": 10,
"totalElements": 35,
"totalPages": 4
}
}