Members
Base URL: https://app.neuroflash.com/api/workspace-service
Manage workspace membership and roles.
Create workspace members
POST
/v1/workspaces/{workspaceId}/workspace-membersResponse
FieldTypeDescription
_embeddedobject
customerobject
emailstringEmail of the customerhadTrialbooleanTrue if the customer has ever started a trial in any workspacelegacyIdintegerID of the customer in the legacy systemnamestringName of the customerpermissionsobjectworkspaceobject
_embeddedobject
avatarobject
_embeddedobject
signedUrlstringcreatedAtstringcreatedByUserIdstringfileNamestringidstringsignedUrlstringstorageKeystringupdatedAtstringworkspaceIdstringbillingContactobject
activeDiscountstringreadonly synced from stripe: true if a discount is active for this stripe customeraddressLine1stringreadonly synced from stripe: First line of the address of the billing contactaddressLine2stringreadonly synced from stripe: Second line of the address of the billing contactcitystringreadonly synced from stripe: City of the billing contactcountrystringreadonly synced from stripe: Country of the billing contactcreatedAtstringcreatedByUserIdstringdefaultPaymentCardNumberLastFourDigitsstringdefaultPaymentMethodstringdefaultPaymentMethodCardBrandstringemailstringEmail address of the billing contactidstringimportedFromLegacyCustomerIdintegerDeprecated: only needed while import from legacy api is still active ID of the legacy customer this was imported fromnamestringName of the billing contactpostalCodestringreadonly synced from stripe: Postal code of the billing contactstatestringreadonly synced from stripe: State of the billing contactstripeCustomerIdstringStripe customer ID for billing purposes. Could become optional if we add other payment providersupdatedAtstringcurrentSubscriptionobject
_embeddedobject
availableWordsintegerdeprecated: fields are there until frontend removes all the usages default values are used, no adjustments are made! it always reports that the workspace is on an unlimited plannewPricingPlanobject
activebooleanset to true when this pricingPlan can be configured on existing and new subscriptionsbillingIntervalstringcategoryIdstringID of the category this plan belongs todisplayNamestringname used for internal purposes like the admin-ui or hubspot. Should not be displayed to customersidstringid of the pricing planimportedFromLegacyIdintegerisDefaultbooleanIs this the default plan for new customers?priceInEuronumberhow much the customer needs to pay for this subscriptionpricePerCurrencyobjectA map of string keys to float valuesstripeBillingPortalEnabledbooleantrue if subscriptions with this pricingPlan can be self-managed in the stripe billing portalstripePriceIdstringID of the price in stripestripeTrackTokenMeterstringstripeTrackUsagebooleandeprecatedtierintegertrialDaysintegerhow many trial days are allowed for this planpricingPlanobject
activebooleanset to true when this pricingPlan can be configured on existing and new subscriptionsbillingIntervalstringcategoryIdstringID of the category this plan belongs todisplayNamestringname used for internal purposes like the admin-ui or hubspot. Should not be displayed to customersidstringid of the pricing planimportedFromLegacyIdintegerisDefaultbooleanIs this the default plan for new customers?priceInEuronumberhow much the customer needs to pay for this subscriptionpricePerCurrencyobjectA map of string keys to float valuesstripeBillingPortalEnabledbooleantrue if subscriptions with this pricingPlan can be self-managed in the stripe billing portalstripePriceIdstringID of the price in stripestripeTrackTokenMeterstringstripeTrackUsagebooleandeprecatedtierintegertrialDaysintegerhow many trial days are allowed for this planpricingPlanCategoryobject
displayNamestringidstringtranslationKeystringactivebooleanFlag indicating whether the subscription is active. Subscriptions can become inactive if they are paused or have more members than the current plan allowsactiveDiscountsarray<string>readonly synced from stripe: true if a discount is active for this stripe subscriptionavailableWordsintegercreatedAtstringcreatedByUserIdstringcurrencystringendDatestringreadonly synced from Stripe: date at which this subscription will automatically be cancelledidstringimportedFromLegacyCustomerIdintegerDeprecated: only needed while import from legacy api is still active ID of the legacy customer this was imported fromisGracePeriodbooleantrue if the subscription will be cancelled at a set date in the futureisTrialbooleantrue if this is currently a trial periodlimitRenewalDatestringnext date on which the limits (like words available, images available etc) will be reset. This happens every month, starting with the start of the subscriptionnextSubscriptionCycleStartstringreadonly 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 planpaymentCardNumberLastFourDigitsstringreadonly 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 invoicepaymentMethodCardBrandstringpaymentPausedbooleanreadonly 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 inactivepaymentTypestringpricingPlanIdstringpricingPlanWordsintegerdeprecated: fields are there until frontend removes all the usages default values are used, no adjustments are made! it always reports that the workspace is on an unlimited plansepaPaymentFailedbooleanreadonly synced from Stripe: Flag indicating whether the SEPA payment has failedspilloverWordsintegerstripeStatusstringstripeSubscriptionIdstringStripe subscription IDstripeSubscriptionItemIdstringID of the subscription item in stripe (subscriptions should only have one item)trialEndsAtstringreadonly synced from Stripe: Timestamp when the trial period endstrialStartedAtstringreadonly synced from stripe: if a trial is in progress, date when it startedupdatedAtstringusedWordsintegerworkspaceIdstringID of the workspace this subscription belongs tobillingContactIdstringID of the billing contact for this workspacecreatedAtstringcreatedByUserIdstringcurrentSubscriptionIdstringID of the current subscription for this workspacefirstMemberInvitedAtstringdeprecated Timestamp when the first member was invited to the workspacefirstPaidSubscriptionAtstringIf this workspace ever had a paid subscription, this contains the date at which the first one startedidstringimportedFromLegacyCustomerIdintegerdeprecated 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 subscriptionimportedFromLegacyTeamIdintegerdeprecated: fields that are currently still needed for the legacy system ID of the legacy team this workspace was imported fromkeystringHuman readable unique identifier of the workspacekeyIndexintegerUnique auto generated index which is used to generate a unique keynamestringName of the workspacetrialStartedAtstringIf this workspace ever had a subscription with a trial this contains the time when it was startedupdatedAtstringcreatedAtstringcreatedByUserIdstringidstringimportedFromLegacyCustomerIdintegerdeprecated 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 fromlegacyCustomerIdintegerID of the legacy customerrolestringRole of the member in the workspaceupdatedAtstringuserIdstringID of the userworkspaceIdstringID of the workspace the member belongs toExample
- cURL
- Python
- Node.js
- Go
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 '{}'
import requests
response = requests.post(
f"https://app.neuroflash.com/api/workspace-service/v1/workspaces/{workspace_id}/workspace-members",
headers={"Authorization": f"Bearer {token}"},
).json()
const response = await fetch(
`https://app.neuroflash.com/api/workspace-service/v1/workspaces/${workspaceId}/workspace-members`,
{
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
}
).then((r) => r.json());
body, _ := json.Marshal(map[string]any{})
req, _ := http.NewRequest("POST", "https://app.neuroflash.com/api/workspace-service/v1/workspaces/"+workspaceID+"/workspace-members", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
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": "...",
"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"
}
Get workspace members
GET
/v1/workspaces/{workspaceId}/workspace-membersPath Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
workspaceId | string | Yes | workspaceId |
Response
FieldTypeDescription
dataarray<object>
_embeddedobject
customerobject
emailstringEmail of the customerhadTrialbooleanTrue if the customer has ever started a trial in any workspacelegacyIdintegerID of the customer in the legacy systemnamestringName of the customerpermissionsobjectworkspaceobject
_embeddedobject
avatarobject
_embeddedobject
signedUrlstringcreatedAtstringcreatedByUserIdstringfileNamestringidstringsignedUrlstringstorageKeystringupdatedAtstringworkspaceIdstringbillingContactobject
activeDiscountstringreadonly synced from stripe: true if a discount is active for this stripe customeraddressLine1stringreadonly synced from stripe: First line of the address of the billing contactaddressLine2stringreadonly synced from stripe: Second line of the address of the billing contactcitystringreadonly synced from stripe: City of the billing contactcountrystringreadonly synced from stripe: Country of the billing contactcreatedAtstringcreatedByUserIdstringdefaultPaymentCardNumberLastFourDigitsstringdefaultPaymentMethodstringdefaultPaymentMethodCardBrandstringemailstringEmail address of the billing contactidstringimportedFromLegacyCustomerIdintegerDeprecated: only needed while import from legacy api is still active ID of the legacy customer this was imported fromnamestringName of the billing contactpostalCodestringreadonly synced from stripe: Postal code of the billing contactstatestringreadonly synced from stripe: State of the billing contactstripeCustomerIdstringStripe customer ID for billing purposes. Could become optional if we add other payment providersupdatedAtstringcurrentSubscriptionobject
_embeddedobject
availableWordsintegerdeprecated: fields are there until frontend removes all the usages default values are used, no adjustments are made! it always reports that the workspace is on an unlimited plannewPricingPlanobject
activebooleanset to true when this pricingPlan can be configured on existing and new subscriptionsbillingIntervalstringcategoryIdstringID of the category this plan belongs todisplayNamestringname used for internal purposes like the admin-ui or hubspot. Should not be displayed to customersidstringid of the pricing planimportedFromLegacyIdintegerisDefaultbooleanIs this the default plan for new customers?priceInEuronumberhow much the customer needs to pay for this subscriptionpricePerCurrencyobjectA map of string keys to float valuesstripeBillingPortalEnabledbooleantrue if subscriptions with this pricingPlan can be self-managed in the stripe billing portalstripePriceIdstringID of the price in stripestripeTrackTokenMeterstringstripeTrackUsagebooleandeprecatedtierintegertrialDaysintegerhow many trial days are allowed for this planpricingPlanobject
activebooleanset to true when this pricingPlan can be configured on existing and new subscriptionsbillingIntervalstringcategoryIdstringID of the category this plan belongs todisplayNamestringname used for internal purposes like the admin-ui or hubspot. Should not be displayed to customersidstringid of the pricing planimportedFromLegacyIdintegerisDefaultbooleanIs this the default plan for new customers?priceInEuronumberhow much the customer needs to pay for this subscriptionpricePerCurrencyobjectA map of string keys to float valuesstripeBillingPortalEnabledbooleantrue if subscriptions with this pricingPlan can be self-managed in the stripe billing portalstripePriceIdstringID of the price in stripestripeTrackTokenMeterstringstripeTrackUsagebooleandeprecatedtierintegertrialDaysintegerhow many trial days are allowed for this planpricingPlanCategoryobject
displayNamestringidstringtranslationKeystringactivebooleanFlag indicating whether the subscription is active. Subscriptions can become inactive if they are paused or have more members than the current plan allowsactiveDiscountsarray<string>readonly synced from stripe: true if a discount is active for this stripe subscriptionavailableWordsintegercreatedAtstringcreatedByUserIdstringcurrencystringendDatestringreadonly synced from Stripe: date at which this subscription will automatically be cancelledidstringimportedFromLegacyCustomerIdintegerDeprecated: only needed while import from legacy api is still active ID of the legacy customer this was imported fromisGracePeriodbooleantrue if the subscription will be cancelled at a set date in the futureisTrialbooleantrue if this is currently a trial periodlimitRenewalDatestringnext date on which the limits (like words available, images available etc) will be reset. This happens every month, starting with the start of the subscriptionnextSubscriptionCycleStartstringreadonly 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 planpaymentCardNumberLastFourDigitsstringreadonly 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 invoicepaymentMethodCardBrandstringpaymentPausedbooleanreadonly 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 inactivepaymentTypestringpricingPlanIdstringpricingPlanWordsintegerdeprecated: fields are there until frontend removes all the usages default values are used, no adjustments are made! it always reports that the workspace is on an unlimited plansepaPaymentFailedbooleanreadonly synced from Stripe: Flag indicating whether the SEPA payment has failedspilloverWordsintegerstripeStatusstringstripeSubscriptionIdstringStripe subscription IDstripeSubscriptionItemIdstringID of the subscription item in stripe (subscriptions should only have one item)trialEndsAtstringreadonly synced from Stripe: Timestamp when the trial period endstrialStartedAtstringreadonly synced from stripe: if a trial is in progress, date when it startedupdatedAtstringusedWordsintegerworkspaceIdstringID of the workspace this subscription belongs tobillingContactIdstringID of the billing contact for this workspacecreatedAtstringcreatedByUserIdstringcurrentSubscriptionIdstringID of the current subscription for this workspacefirstMemberInvitedAtstringdeprecated Timestamp when the first member was invited to the workspacefirstPaidSubscriptionAtstringIf this workspace ever had a paid subscription, this contains the date at which the first one startedidstringimportedFromLegacyCustomerIdintegerdeprecated 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 subscriptionimportedFromLegacyTeamIdintegerdeprecated: fields that are currently still needed for the legacy system ID of the legacy team this workspace was imported fromkeystringHuman readable unique identifier of the workspacekeyIndexintegerUnique auto generated index which is used to generate a unique keynamestringName of the workspacetrialStartedAtstringIf this workspace ever had a subscription with a trial this contains the time when it was startedupdatedAtstringcreatedAtstringcreatedByUserIdstringidstringimportedFromLegacyCustomerIdintegerdeprecated 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 fromlegacyCustomerIdintegerID of the legacy customerrolestringRole of the member in the workspaceupdatedAtstringuserIdstringID of the userworkspaceIdstringID of the workspace the member belongs topageobject
currentPageintegersizeintegertotalElementsintegertotalPagesintegerExample
- cURL
- Python
- Node.js
- Go
curl "https://app.neuroflash.com/api/workspace-service/v1/workspaces/{workspace_id}/workspace-members" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
import requests
response = requests.get(
f"https://app.neuroflash.com/api/workspace-service/v1/workspaces/{workspace_id}/workspace-members",
headers={"Authorization": f"Bearer {token}"},
).json()
const response = await fetch(
`https://app.neuroflash.com/api/workspace-service/v1/workspaces/${workspaceId}/workspace-members`,
{ headers: { Authorization: `Bearer ${token}` } }
).then((r) => r.json());
req, _ := http.NewRequest("GET", "https://app.neuroflash.com/api/workspace-service/v1/workspaces/"+workspaceID+"/workspace-members", nil)
req.Header.Set("Authorization", "Bearer "+token)
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
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
GET
/v1/workspaces/{workspaceId}/workspace-members/{memberId}Response
FieldTypeDescription
_embeddedobject
customerobject
emailstringEmail of the customerhadTrialbooleanTrue if the customer has ever started a trial in any workspacelegacyIdintegerID of the customer in the legacy systemnamestringName of the customerpermissionsobjectworkspaceobject
_embeddedobject
avatarobject
_embeddedobject
signedUrlstringcreatedAtstringcreatedByUserIdstringfileNamestringidstringsignedUrlstringstorageKeystringupdatedAtstringworkspaceIdstringbillingContactobject
activeDiscountstringreadonly synced from stripe: true if a discount is active for this stripe customeraddressLine1stringreadonly synced from stripe: First line of the address of the billing contactaddressLine2stringreadonly synced from stripe: Second line of the address of the billing contactcitystringreadonly synced from stripe: City of the billing contactcountrystringreadonly synced from stripe: Country of the billing contactcreatedAtstringcreatedByUserIdstringdefaultPaymentCardNumberLastFourDigitsstringdefaultPaymentMethodstringdefaultPaymentMethodCardBrandstringemailstringEmail address of the billing contactidstringimportedFromLegacyCustomerIdintegerDeprecated: only needed while import from legacy api is still active ID of the legacy customer this was imported fromnamestringName of the billing contactpostalCodestringreadonly synced from stripe: Postal code of the billing contactstatestringreadonly synced from stripe: State of the billing contactstripeCustomerIdstringStripe customer ID for billing purposes. Could become optional if we add other payment providersupdatedAtstringcurrentSubscriptionobject
_embeddedobject
availableWordsintegerdeprecated: fields are there until frontend removes all the usages default values are used, no adjustments are made! it always reports that the workspace is on an unlimited plannewPricingPlanobject
activebooleanset to true when this pricingPlan can be configured on existing and new subscriptionsbillingIntervalstringcategoryIdstringID of the category this plan belongs todisplayNamestringname used for internal purposes like the admin-ui or hubspot. Should not be displayed to customersidstringid of the pricing planimportedFromLegacyIdintegerisDefaultbooleanIs this the default plan for new customers?priceInEuronumberhow much the customer needs to pay for this subscriptionpricePerCurrencyobjectA map of string keys to float valuesstripeBillingPortalEnabledbooleantrue if subscriptions with this pricingPlan can be self-managed in the stripe billing portalstripePriceIdstringID of the price in stripestripeTrackTokenMeterstringstripeTrackUsagebooleandeprecatedtierintegertrialDaysintegerhow many trial days are allowed for this planpricingPlanobject
activebooleanset to true when this pricingPlan can be configured on existing and new subscriptionsbillingIntervalstringcategoryIdstringID of the category this plan belongs todisplayNamestringname used for internal purposes like the admin-ui or hubspot. Should not be displayed to customersidstringid of the pricing planimportedFromLegacyIdintegerisDefaultbooleanIs this the default plan for new customers?priceInEuronumberhow much the customer needs to pay for this subscriptionpricePerCurrencyobjectA map of string keys to float valuesstripeBillingPortalEnabledbooleantrue if subscriptions with this pricingPlan can be self-managed in the stripe billing portalstripePriceIdstringID of the price in stripestripeTrackTokenMeterstringstripeTrackUsagebooleandeprecatedtierintegertrialDaysintegerhow many trial days are allowed for this planpricingPlanCategoryobject
displayNamestringidstringtranslationKeystringactivebooleanFlag indicating whether the subscription is active. Subscriptions can become inactive if they are paused or have more members than the current plan allowsactiveDiscountsarray<string>readonly synced from stripe: true if a discount is active for this stripe subscriptionavailableWordsintegercreatedAtstringcreatedByUserIdstringcurrencystringendDatestringreadonly synced from Stripe: date at which this subscription will automatically be cancelledidstringimportedFromLegacyCustomerIdintegerDeprecated: only needed while import from legacy api is still active ID of the legacy customer this was imported fromisGracePeriodbooleantrue if the subscription will be cancelled at a set date in the futureisTrialbooleantrue if this is currently a trial periodlimitRenewalDatestringnext date on which the limits (like words available, images available etc) will be reset. This happens every month, starting with the start of the subscriptionnextSubscriptionCycleStartstringreadonly 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 planpaymentCardNumberLastFourDigitsstringreadonly 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 invoicepaymentMethodCardBrandstringpaymentPausedbooleanreadonly 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 inactivepaymentTypestringpricingPlanIdstringpricingPlanWordsintegerdeprecated: fields are there until frontend removes all the usages default values are used, no adjustments are made! it always reports that the workspace is on an unlimited plansepaPaymentFailedbooleanreadonly synced from Stripe: Flag indicating whether the SEPA payment has failedspilloverWordsintegerstripeStatusstringstripeSubscriptionIdstringStripe subscription IDstripeSubscriptionItemIdstringID of the subscription item in stripe (subscriptions should only have one item)trialEndsAtstringreadonly synced from Stripe: Timestamp when the trial period endstrialStartedAtstringreadonly synced from stripe: if a trial is in progress, date when it startedupdatedAtstringusedWordsintegerworkspaceIdstringID of the workspace this subscription belongs tobillingContactIdstringID of the billing contact for this workspacecreatedAtstringcreatedByUserIdstringcurrentSubscriptionIdstringID of the current subscription for this workspacefirstMemberInvitedAtstringdeprecated Timestamp when the first member was invited to the workspacefirstPaidSubscriptionAtstringIf this workspace ever had a paid subscription, this contains the date at which the first one startedidstringimportedFromLegacyCustomerIdintegerdeprecated 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 subscriptionimportedFromLegacyTeamIdintegerdeprecated: fields that are currently still needed for the legacy system ID of the legacy team this workspace was imported fromkeystringHuman readable unique identifier of the workspacekeyIndexintegerUnique auto generated index which is used to generate a unique keynamestringName of the workspacetrialStartedAtstringIf this workspace ever had a subscription with a trial this contains the time when it was startedupdatedAtstringcreatedAtstringcreatedByUserIdstringidstringimportedFromLegacyCustomerIdintegerdeprecated 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 fromlegacyCustomerIdintegerID of the legacy customerrolestringRole of the member in the workspaceupdatedAtstringuserIdstringID of the userworkspaceIdstringID of the workspace the member belongs toExample
- cURL
- Python
- Node.js
- Go
curl "https://app.neuroflash.com/api/workspace-service/v1/workspaces/{workspace_id}/workspace-members/{member_id}" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
import requests
response = requests.get(
f"https://app.neuroflash.com/api/workspace-service/v1/workspaces/{workspace_id}/workspace-members/{member_id}",
headers={"Authorization": f"Bearer {token}"},
).json()
const response = await fetch(
`https://app.neuroflash.com/api/workspace-service/v1/workspaces/${workspaceId}/workspace-members/${memberId}`,
{ headers: { Authorization: `Bearer ${token}` } }
).then((r) => r.json());
req, _ := http.NewRequest("GET", "https://app.neuroflash.com/api/workspace-service/v1/workspaces/"+workspaceID+"/workspace-members/"+memberID+"", nil)
req.Header.Set("Authorization", "Bearer "+token)
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
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": "...",
"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
PUT
/v1/workspaces/{workspaceId}/workspace-members/{memberId}Response
FieldTypeDescription
_embeddedobject
customerobject
emailstringEmail of the customerhadTrialbooleanTrue if the customer has ever started a trial in any workspacelegacyIdintegerID of the customer in the legacy systemnamestringName of the customerpermissionsobjectworkspaceobject
_embeddedobject
avatarobject
_embeddedobject
signedUrlstringcreatedAtstringcreatedByUserIdstringfileNamestringidstringsignedUrlstringstorageKeystringupdatedAtstringworkspaceIdstringbillingContactobject
activeDiscountstringreadonly synced from stripe: true if a discount is active for this stripe customeraddressLine1stringreadonly synced from stripe: First line of the address of the billing contactaddressLine2stringreadonly synced from stripe: Second line of the address of the billing contactcitystringreadonly synced from stripe: City of the billing contactcountrystringreadonly synced from stripe: Country of the billing contactcreatedAtstringcreatedByUserIdstringdefaultPaymentCardNumberLastFourDigitsstringdefaultPaymentMethodstringdefaultPaymentMethodCardBrandstringemailstringEmail address of the billing contactidstringimportedFromLegacyCustomerIdintegerDeprecated: only needed while import from legacy api is still active ID of the legacy customer this was imported fromnamestringName of the billing contactpostalCodestringreadonly synced from stripe: Postal code of the billing contactstatestringreadonly synced from stripe: State of the billing contactstripeCustomerIdstringStripe customer ID for billing purposes. Could become optional if we add other payment providersupdatedAtstringcurrentSubscriptionobject
_embeddedobject
availableWordsintegerdeprecated: fields are there until frontend removes all the usages default values are used, no adjustments are made! it always reports that the workspace is on an unlimited plannewPricingPlanobject
activebooleanset to true when this pricingPlan can be configured on existing and new subscriptionsbillingIntervalstringcategoryIdstringID of the category this plan belongs todisplayNamestringname used for internal purposes like the admin-ui or hubspot. Should not be displayed to customersidstringid of the pricing planimportedFromLegacyIdintegerisDefaultbooleanIs this the default plan for new customers?priceInEuronumberhow much the customer needs to pay for this subscriptionpricePerCurrencyobjectA map of string keys to float valuesstripeBillingPortalEnabledbooleantrue if subscriptions with this pricingPlan can be self-managed in the stripe billing portalstripePriceIdstringID of the price in stripestripeTrackTokenMeterstringstripeTrackUsagebooleandeprecatedtierintegertrialDaysintegerhow many trial days are allowed for this planpricingPlanobject
activebooleanset to true when this pricingPlan can be configured on existing and new subscriptionsbillingIntervalstringcategoryIdstringID of the category this plan belongs todisplayNamestringname used for internal purposes like the admin-ui or hubspot. Should not be displayed to customersidstringid of the pricing planimportedFromLegacyIdintegerisDefaultbooleanIs this the default plan for new customers?priceInEuronumberhow much the customer needs to pay for this subscriptionpricePerCurrencyobjectA map of string keys to float valuesstripeBillingPortalEnabledbooleantrue if subscriptions with this pricingPlan can be self-managed in the stripe billing portalstripePriceIdstringID of the price in stripestripeTrackTokenMeterstringstripeTrackUsagebooleandeprecatedtierintegertrialDaysintegerhow many trial days are allowed for this planpricingPlanCategoryobject
displayNamestringidstringtranslationKeystringactivebooleanFlag indicating whether the subscription is active. Subscriptions can become inactive if they are paused or have more members than the current plan allowsactiveDiscountsarray<string>readonly synced from stripe: true if a discount is active for this stripe subscriptionavailableWordsintegercreatedAtstringcreatedByUserIdstringcurrencystringendDatestringreadonly synced from Stripe: date at which this subscription will automatically be cancelledidstringimportedFromLegacyCustomerIdintegerDeprecated: only needed while import from legacy api is still active ID of the legacy customer this was imported fromisGracePeriodbooleantrue if the subscription will be cancelled at a set date in the futureisTrialbooleantrue if this is currently a trial periodlimitRenewalDatestringnext date on which the limits (like words available, images available etc) will be reset. This happens every month, starting with the start of the subscriptionnextSubscriptionCycleStartstringreadonly 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 planpaymentCardNumberLastFourDigitsstringreadonly 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 invoicepaymentMethodCardBrandstringpaymentPausedbooleanreadonly 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 inactivepaymentTypestringpricingPlanIdstringpricingPlanWordsintegerdeprecated: fields are there until frontend removes all the usages default values are used, no adjustments are made! it always reports that the workspace is on an unlimited plansepaPaymentFailedbooleanreadonly synced from Stripe: Flag indicating whether the SEPA payment has failedspilloverWordsintegerstripeStatusstringstripeSubscriptionIdstringStripe subscription IDstripeSubscriptionItemIdstringID of the subscription item in stripe (subscriptions should only have one item)trialEndsAtstringreadonly synced from Stripe: Timestamp when the trial period endstrialStartedAtstringreadonly synced from stripe: if a trial is in progress, date when it startedupdatedAtstringusedWordsintegerworkspaceIdstringID of the workspace this subscription belongs tobillingContactIdstringID of the billing contact for this workspacecreatedAtstringcreatedByUserIdstringcurrentSubscriptionIdstringID of the current subscription for this workspacefirstMemberInvitedAtstringdeprecated Timestamp when the first member was invited to the workspacefirstPaidSubscriptionAtstringIf this workspace ever had a paid subscription, this contains the date at which the first one startedidstringimportedFromLegacyCustomerIdintegerdeprecated 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 subscriptionimportedFromLegacyTeamIdintegerdeprecated: fields that are currently still needed for the legacy system ID of the legacy team this workspace was imported fromkeystringHuman readable unique identifier of the workspacekeyIndexintegerUnique auto generated index which is used to generate a unique keynamestringName of the workspacetrialStartedAtstringIf this workspace ever had a subscription with a trial this contains the time when it was startedupdatedAtstringcreatedAtstringcreatedByUserIdstringidstringimportedFromLegacyCustomerIdintegerdeprecated 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 fromlegacyCustomerIdintegerID of the legacy customerrolestringRole of the member in the workspaceupdatedAtstringuserIdstringID of the userworkspaceIdstringID of the workspace the member belongs toExample
- cURL
- Python
- Node.js
- Go
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 '{}'
import requests
response = requests.put(
f"https://app.neuroflash.com/api/workspace-service/v1/workspaces/{workspace_id}/workspace-members/{member_id}",
headers={"Authorization": f"Bearer {token}"},
).json()
const response = await fetch(
`https://app.neuroflash.com/api/workspace-service/v1/workspaces/${workspaceId}/workspace-members/${memberId}`,
{
method: "PUT",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
}
).then((r) => r.json());
body, _ := json.Marshal(map[string]any{})
req, _ := http.NewRequest("PUT", "https://app.neuroflash.com/api/workspace-service/v1/workspaces/"+workspaceID+"/workspace-members/"+memberID+"", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
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": "...",
"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
DELETE
/v1/workspaces/{workspaceId}/workspace-members/{memberId}Example
- cURL
- Python
- Node.js
- Go
curl -X DELETE "https://app.neuroflash.com/api/workspace-service/v1/workspaces/{workspace_id}/workspace-members/{member_id}" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
import requests
requests.delete(
f"https://app.neuroflash.com/api/workspace-service/v1/workspaces/{workspace_id}/workspace-members/{member_id}",
headers={"Authorization": f"Bearer {token}"},
)
await fetch(
`https://app.neuroflash.com/api/workspace-service/v1/workspaces/${workspaceId}/workspace-members/${memberId}`,
{
method: "DELETE",
headers: { Authorization: `Bearer ${token}` },
}
);
req, _ := http.NewRequest("DELETE", "https://app.neuroflash.com/api/workspace-service/v1/workspaces/"+workspaceID+"/workspace-members/"+memberID+"", nil)
req.Header.Set("Authorization", "Bearer "+token)
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
Get workspace members
GET
/v1/customers/{customerId}/workspace-membersPath Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
customerId | string | Yes | customerId |
Response
FieldTypeDescription
dataarray<object>
_embeddedobject
customerobject
emailstringEmail of the customerhadTrialbooleanTrue if the customer has ever started a trial in any workspacelegacyIdintegerID of the customer in the legacy systemnamestringName of the customerpermissionsobjectworkspaceobject
_embeddedobject
avatarobject
_embeddedobject
signedUrlstringcreatedAtstringcreatedByUserIdstringfileNamestringidstringsignedUrlstringstorageKeystringupdatedAtstringworkspaceIdstringbillingContactobject
activeDiscountstringreadonly synced from stripe: true if a discount is active for this stripe customeraddressLine1stringreadonly synced from stripe: First line of the address of the billing contactaddressLine2stringreadonly synced from stripe: Second line of the address of the billing contactcitystringreadonly synced from stripe: City of the billing contactcountrystringreadonly synced from stripe: Country of the billing contactcreatedAtstringcreatedByUserIdstringdefaultPaymentCardNumberLastFourDigitsstringdefaultPaymentMethodstringdefaultPaymentMethodCardBrandstringemailstringEmail address of the billing contactidstringimportedFromLegacyCustomerIdintegerDeprecated: only needed while import from legacy api is still active ID of the legacy customer this was imported fromnamestringName of the billing contactpostalCodestringreadonly synced from stripe: Postal code of the billing contactstatestringreadonly synced from stripe: State of the billing contactstripeCustomerIdstringStripe customer ID for billing purposes. Could become optional if we add other payment providersupdatedAtstringcurrentSubscriptionobject
_embeddedobject
availableWordsintegerdeprecated: fields are there until frontend removes all the usages default values are used, no adjustments are made! it always reports that the workspace is on an unlimited plannewPricingPlanobject
activebooleanset to true when this pricingPlan can be configured on existing and new subscriptionsbillingIntervalstringcategoryIdstringID of the category this plan belongs todisplayNamestringname used for internal purposes like the admin-ui or hubspot. Should not be displayed to customersidstringid of the pricing planimportedFromLegacyIdintegerisDefaultbooleanIs this the default plan for new customers?priceInEuronumberhow much the customer needs to pay for this subscriptionpricePerCurrencyobjectA map of string keys to float valuesstripeBillingPortalEnabledbooleantrue if subscriptions with this pricingPlan can be self-managed in the stripe billing portalstripePriceIdstringID of the price in stripestripeTrackTokenMeterstringstripeTrackUsagebooleandeprecatedtierintegertrialDaysintegerhow many trial days are allowed for this planpricingPlanobject
activebooleanset to true when this pricingPlan can be configured on existing and new subscriptionsbillingIntervalstringcategoryIdstringID of the category this plan belongs todisplayNamestringname used for internal purposes like the admin-ui or hubspot. Should not be displayed to customersidstringid of the pricing planimportedFromLegacyIdintegerisDefaultbooleanIs this the default plan for new customers?priceInEuronumberhow much the customer needs to pay for this subscriptionpricePerCurrencyobjectA map of string keys to float valuesstripeBillingPortalEnabledbooleantrue if subscriptions with this pricingPlan can be self-managed in the stripe billing portalstripePriceIdstringID of the price in stripestripeTrackTokenMeterstringstripeTrackUsagebooleandeprecatedtierintegertrialDaysintegerhow many trial days are allowed for this planpricingPlanCategoryobject
displayNamestringidstringtranslationKeystringactivebooleanFlag indicating whether the subscription is active. Subscriptions can become inactive if they are paused or have more members than the current plan allowsactiveDiscountsarray<string>readonly synced from stripe: true if a discount is active for this stripe subscriptionavailableWordsintegercreatedAtstringcreatedByUserIdstringcurrencystringendDatestringreadonly synced from Stripe: date at which this subscription will automatically be cancelledidstringimportedFromLegacyCustomerIdintegerDeprecated: only needed while import from legacy api is still active ID of the legacy customer this was imported fromisGracePeriodbooleantrue if the subscription will be cancelled at a set date in the futureisTrialbooleantrue if this is currently a trial periodlimitRenewalDatestringnext date on which the limits (like words available, images available etc) will be reset. This happens every month, starting with the start of the subscriptionnextSubscriptionCycleStartstringreadonly 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 planpaymentCardNumberLastFourDigitsstringreadonly 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 invoicepaymentMethodCardBrandstringpaymentPausedbooleanreadonly 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 inactivepaymentTypestringpricingPlanIdstringpricingPlanWordsintegerdeprecated: fields are there until frontend removes all the usages default values are used, no adjustments are made! it always reports that the workspace is on an unlimited plansepaPaymentFailedbooleanreadonly synced from Stripe: Flag indicating whether the SEPA payment has failedspilloverWordsintegerstripeStatusstringstripeSubscriptionIdstringStripe subscription IDstripeSubscriptionItemIdstringID of the subscription item in stripe (subscriptions should only have one item)trialEndsAtstringreadonly synced from Stripe: Timestamp when the trial period endstrialStartedAtstringreadonly synced from stripe: if a trial is in progress, date when it startedupdatedAtstringusedWordsintegerworkspaceIdstringID of the workspace this subscription belongs tobillingContactIdstringID of the billing contact for this workspacecreatedAtstringcreatedByUserIdstringcurrentSubscriptionIdstringID of the current subscription for this workspacefirstMemberInvitedAtstringdeprecated Timestamp when the first member was invited to the workspacefirstPaidSubscriptionAtstringIf this workspace ever had a paid subscription, this contains the date at which the first one startedidstringimportedFromLegacyCustomerIdintegerdeprecated 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 subscriptionimportedFromLegacyTeamIdintegerdeprecated: fields that are currently still needed for the legacy system ID of the legacy team this workspace was imported fromkeystringHuman readable unique identifier of the workspacekeyIndexintegerUnique auto generated index which is used to generate a unique keynamestringName of the workspacetrialStartedAtstringIf this workspace ever had a subscription with a trial this contains the time when it was startedupdatedAtstringcreatedAtstringcreatedByUserIdstringidstringimportedFromLegacyCustomerIdintegerdeprecated 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 fromlegacyCustomerIdintegerID of the legacy customerrolestringRole of the member in the workspaceupdatedAtstringuserIdstringID of the userworkspaceIdstringID of the workspace the member belongs topageobject
currentPageintegersizeintegertotalElementsintegertotalPagesintegerExample
- cURL
- Python
- Node.js
- Go
curl "https://app.neuroflash.com/api/workspace-service/v1/customers/{customer_id}/workspace-members" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
import requests
response = requests.get(
f"https://app.neuroflash.com/api/workspace-service/v1/customers/{customer_id}/workspace-members",
headers={"Authorization": f"Bearer {token}"},
).json()
const response = await fetch(
`https://app.neuroflash.com/api/workspace-service/v1/customers/${customerId}/workspace-members`,
{ headers: { Authorization: `Bearer ${token}` } }
).then((r) => r.json());
req, _ := http.NewRequest("GET", "https://app.neuroflash.com/api/workspace-service/v1/customers/"+customerID+"/workspace-members", nil)
req.Header.Set("Authorization", "Bearer "+token)
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
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 workspace members
GET
/v1/users/{userId}/workspace-membersPath Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
userId | string | Yes | userId |
Response
FieldTypeDescription
dataarray<object>
_embeddedobject
customerobject
emailstringEmail of the customerhadTrialbooleanTrue if the customer has ever started a trial in any workspacelegacyIdintegerID of the customer in the legacy systemnamestringName of the customerpermissionsobjectworkspaceobject
_embeddedobject
avatarobject
_embeddedobject
signedUrlstringcreatedAtstringcreatedByUserIdstringfileNamestringidstringsignedUrlstringstorageKeystringupdatedAtstringworkspaceIdstringbillingContactobject
activeDiscountstringreadonly synced from stripe: true if a discount is active for this stripe customeraddressLine1stringreadonly synced from stripe: First line of the address of the billing contactaddressLine2stringreadonly synced from stripe: Second line of the address of the billing contactcitystringreadonly synced from stripe: City of the billing contactcountrystringreadonly synced from stripe: Country of the billing contactcreatedAtstringcreatedByUserIdstringdefaultPaymentCardNumberLastFourDigitsstringdefaultPaymentMethodstringdefaultPaymentMethodCardBrandstringemailstringEmail address of the billing contactidstringimportedFromLegacyCustomerIdintegerDeprecated: only needed while import from legacy api is still active ID of the legacy customer this was imported fromnamestringName of the billing contactpostalCodestringreadonly synced from stripe: Postal code of the billing contactstatestringreadonly synced from stripe: State of the billing contactstripeCustomerIdstringStripe customer ID for billing purposes. Could become optional if we add other payment providersupdatedAtstringcurrentSubscriptionobject
_embeddedobject
availableWordsintegerdeprecated: fields are there until frontend removes all the usages default values are used, no adjustments are made! it always reports that the workspace is on an unlimited plannewPricingPlanobject
activebooleanset to true when this pricingPlan can be configured on existing and new subscriptionsbillingIntervalstringcategoryIdstringID of the category this plan belongs todisplayNamestringname used for internal purposes like the admin-ui or hubspot. Should not be displayed to customersidstringid of the pricing planimportedFromLegacyIdintegerisDefaultbooleanIs this the default plan for new customers?priceInEuronumberhow much the customer needs to pay for this subscriptionpricePerCurrencyobjectA map of string keys to float valuesstripeBillingPortalEnabledbooleantrue if subscriptions with this pricingPlan can be self-managed in the stripe billing portalstripePriceIdstringID of the price in stripestripeTrackTokenMeterstringstripeTrackUsagebooleandeprecatedtierintegertrialDaysintegerhow many trial days are allowed for this planpricingPlanobject
activebooleanset to true when this pricingPlan can be configured on existing and new subscriptionsbillingIntervalstringcategoryIdstringID of the category this plan belongs todisplayNamestringname used for internal purposes like the admin-ui or hubspot. Should not be displayed to customersidstringid of the pricing planimportedFromLegacyIdintegerisDefaultbooleanIs this the default plan for new customers?priceInEuronumberhow much the customer needs to pay for this subscriptionpricePerCurrencyobjectA map of string keys to float valuesstripeBillingPortalEnabledbooleantrue if subscriptions with this pricingPlan can be self-managed in the stripe billing portalstripePriceIdstringID of the price in stripestripeTrackTokenMeterstringstripeTrackUsagebooleandeprecatedtierintegertrialDaysintegerhow many trial days are allowed for this planpricingPlanCategoryobject
displayNamestringidstringtranslationKeystringactivebooleanFlag indicating whether the subscription is active. Subscriptions can become inactive if they are paused or have more members than the current plan allowsactiveDiscountsarray<string>readonly synced from stripe: true if a discount is active for this stripe subscriptionavailableWordsintegercreatedAtstringcreatedByUserIdstringcurrencystringendDatestringreadonly synced from Stripe: date at which this subscription will automatically be cancelledidstringimportedFromLegacyCustomerIdintegerDeprecated: only needed while import from legacy api is still active ID of the legacy customer this was imported fromisGracePeriodbooleantrue if the subscription will be cancelled at a set date in the futureisTrialbooleantrue if this is currently a trial periodlimitRenewalDatestringnext date on which the limits (like words available, images available etc) will be reset. This happens every month, starting with the start of the subscriptionnextSubscriptionCycleStartstringreadonly 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 planpaymentCardNumberLastFourDigitsstringreadonly 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 invoicepaymentMethodCardBrandstringpaymentPausedbooleanreadonly 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 inactivepaymentTypestringpricingPlanIdstringpricingPlanWordsintegerdeprecated: fields are there until frontend removes all the usages default values are used, no adjustments are made! it always reports that the workspace is on an unlimited plansepaPaymentFailedbooleanreadonly synced from Stripe: Flag indicating whether the SEPA payment has failedspilloverWordsintegerstripeStatusstringstripeSubscriptionIdstringStripe subscription IDstripeSubscriptionItemIdstringID of the subscription item in stripe (subscriptions should only have one item)trialEndsAtstringreadonly synced from Stripe: Timestamp when the trial period endstrialStartedAtstringreadonly synced from stripe: if a trial is in progress, date when it startedupdatedAtstringusedWordsintegerworkspaceIdstringID of the workspace this subscription belongs tobillingContactIdstringID of the billing contact for this workspacecreatedAtstringcreatedByUserIdstringcurrentSubscriptionIdstringID of the current subscription for this workspacefirstMemberInvitedAtstringdeprecated Timestamp when the first member was invited to the workspacefirstPaidSubscriptionAtstringIf this workspace ever had a paid subscription, this contains the date at which the first one startedidstringimportedFromLegacyCustomerIdintegerdeprecated 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 subscriptionimportedFromLegacyTeamIdintegerdeprecated: fields that are currently still needed for the legacy system ID of the legacy team this workspace was imported fromkeystringHuman readable unique identifier of the workspacekeyIndexintegerUnique auto generated index which is used to generate a unique keynamestringName of the workspacetrialStartedAtstringIf this workspace ever had a subscription with a trial this contains the time when it was startedupdatedAtstringcreatedAtstringcreatedByUserIdstringidstringimportedFromLegacyCustomerIdintegerdeprecated 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 fromlegacyCustomerIdintegerID of the legacy customerrolestringRole of the member in the workspaceupdatedAtstringuserIdstringID of the userworkspaceIdstringID of the workspace the member belongs topageobject
currentPageintegersizeintegertotalElementsintegertotalPagesintegerExample
- cURL
- Python
- Node.js
- Go
curl "https://app.neuroflash.com/api/workspace-service/v1/users/{user_id}/workspace-members" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
import requests
response = requests.get(
f"https://app.neuroflash.com/api/workspace-service/v1/users/{user_id}/workspace-members",
headers={"Authorization": f"Bearer {token}"},
).json()
const response = await fetch(
`https://app.neuroflash.com/api/workspace-service/v1/users/${userId}/workspace-members`,
{ headers: { Authorization: `Bearer ${token}` } }
).then((r) => r.json());
req, _ := http.NewRequest("GET", "https://app.neuroflash.com/api/workspace-service/v1/users/"+userID+"/workspace-members", nil)
req.Header.Set("Authorization", "Bearer "+token)
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
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
}
}