# Agent skills Source: https://docs.outseta.com/agent-skills Wire Outseta into your app with the Outseta agent toolkit — integration as simple as writing a prompt. Let your agent handle integration. Our agent toolkit packages everything an AI coding agent needs to wire Outseta into your app — auth, billing, and CRM — making it as simple as writing a prompt. ## Install skills Add the toolkit to your project: ```bash theme={null} npx skills add outseta/agent-toolkit ``` This installs the Outseta skills into your project so your agent can reference them while it builds. Once installed, describe what you want in plain language and let your agent do the wiring. # Record a custom event associated to an account, person or deal. Source: https://docs.outseta.com/api-reference/activity/record-a-custom-event-associated-to-an-account-person-or-deal /api-reference/openapi.json post /api/v1/activities/customactivity These activities show up on the activity feed of the corresponding entity and can be leveraged to trigger drip campaigns and other automation. For integration with drip campaigns make sure that what you pass in the Title property matches the start / stop value specified for the campaign. # Retrieve all activities. Source: https://docs.outseta.com/api-reference/activity/retrieve-all-activities /api-reference/openapi.json get /api/v1/activities One or multiple parameters can be defined to filter the results. ActivityType=[100,101] where ActivityUpdated = 100 and AcccountUpdated = 101. Results will be limited to the last year unless ActivityDateTime is specified, possibly with ActivityDateTime__gt/ActivityDateTime__gte and ActivityDateTime__lt/ActivityDateTime__lte. # Create a tag. Source: https://docs.outseta.com/api-reference/attribute/create-a-tag /api-reference/openapi.json post /api/v1/attribute/tags Name and EntityType are required. EntityType fixes what the tag can go on: 4 (Case) for support tickets, 13 (Article) for knowledge base articles, 12 (Broadcast) for broadcast emails, 11 (Segment) for segments. TagColor sets the color the tag shows in. Name must be unique within an entity type. If the name already exists for that entity type, the existing tag is returned instead of a duplicate, and its color is updated when a different TagColor is supplied. SystemName and SystemDescription are set by Outseta and are ignored here. # Delete a tag. Source: https://docs.outseta.com/api-reference/attribute/delete-a-tag /api-reference/openapi.json delete /api/v1/attribute/tags/{tagUid} The tag is also taken off every record that carries it. For a Case tag, it is removed from all support tickets that have it. An Article tag that the knowledge base version filter names cannot be deleted. Take it out of the version filter first, then delete it. # Retrieve a custom attribute definition. Source: https://docs.outseta.com/api-reference/attribute/retrieve-a-custom-attribute-definition /api-reference/openapi.json get /api/v1/attributes/definitions/{definitionUid} The entityType segment of the URL must match the type the definition belongs to (e.g. Account, Person, Deal). # Retrieve a tag. Source: https://docs.outseta.com/api-reference/attribute/retrieve-a-tag /api-reference/openapi.json get /api/v1/attribute/tags/{tagUid} # Retrieve all custom attribute definitions. Source: https://docs.outseta.com/api-reference/attribute/retrieve-all-custom-attribute-definitions /api-reference/openapi.json get /api/v1/attributes/{entityType}/definitions entityType is the name of an EntityType enum value, for example: Account, Person, Deal. Definitions describe the labels, system names, and control types of the custom attributes that have been added to that entity. # Retrieve all tags. Source: https://docs.outseta.com/api-reference/attribute/retrieve-all-tags /api-reference/openapi.json get /api/v1/attribute/tags Each tag applies to a single entity type. Pass entityType to retrieve the tags for one of them, for example entityType=Article for knowledge base article tags. How a tag goes onto a record depends on the entity type. Articles, broadcasts and segments each take tags on a tags sub-resource of the record: - POST /support/articles/{entityUid}/tags and PUT, GET, DELETE on the same path - POST /email/campaigns/broadcasts/{entityUid}/tags and the same for the rest - POST /crm/segments/{entityUid}/tags and the same for the rest A support ticket is the exception. It holds its tags in its own CaseTags collection, so you add and remove ticket tags with PUT /support/cases/{caseUid}. Name is unique within an entity type. SystemName and SystemDescription identify a built-in tag (for example Priority.Urgent) and are set by Outseta. # Update a tag. Source: https://docs.outseta.com/api-reference/attribute/update-a-tag /api-reference/openapi.json put /api/v1/attribute/tags/{tagUid} Use this to rename a tag or to change its color. EntityType cannot be changed after the tag is created. Name must stay unique within the entity type. SystemName and SystemDescription are set by Outseta and cannot be changed. # Add a discount to a subscription. Source: https://docs.outseta.com/api-reference/billing/add-a-discount-to-a-subscription /api-reference/openapi.json post /api/v1/billing/subscriptions/{subscriptionUid}/discounts/{discountUid} # Add a new discount coupon. Source: https://docs.outseta.com/api-reference/billing/add-a-new-discount-coupon /api-reference/openapi.json post /api/v1/billing/discountcoupons Only one of AmountOff or PercentOff should be set. Duration values: 1 = Forever, 2 = Once, 3 = Repeating (DurationInMonths must be set). # Add a new plan. Source: https://docs.outseta.com/api-reference/billing/add-a-new-plan /api-reference/openapi.json post /api/v1/billing/plans # Add a new plan family. Source: https://docs.outseta.com/api-reference/billing/add-a-new-plan-family /api-reference/openapi.json post /api/v1/billing/planfamilies # Add a payment to an invoice. Source: https://docs.outseta.com/api-reference/billing/add-a-payment-to-an-invoice /api-reference/openapi.json post /api/v1/billing/transactions/payment If the amount matches the outstanding amount of the invoice, the invoice will be marked as Paid. # Add a subscription to an account for the first time. Source: https://docs.outseta.com/api-reference/billing/add-a-subscription-to-an-account-for-the-first-time /api-reference/openapi.json put /api/v1/billing/subscriptions/firsttimesubscription Returns an invoice object with information about the amount outstanding. # Add a usage entry for an add-on that bills for usage at the end of the month. Source: https://docs.outseta.com/api-reference/billing/add-a-usage-entry-for-an-add-on-that-bills-for-usage-at-the-end-of-the-month /api-reference/openapi.json post /api/v1/billing/usage # Add an add-on to a subscription. Source: https://docs.outseta.com/api-reference/billing/add-an-add-on-to-a-subscription /api-reference/openapi.json post /api/v1/billing/subscriptionaddons # Change a subscription on an account. Source: https://docs.outseta.com/api-reference/billing/change-a-subscription-on-an-account /api-reference/openapi.json put /api/v1/billing/subscriptions/{subscriptionUid}/changesubscription Returns an invoice object with information about the amount outstanding. # Create an ad-hoc invoice for a given account. Source: https://docs.outseta.com/api-reference/billing/create-an-ad-hoc-invoice-for-a-given-account /api-reference/openapi.json post /api/v1/billing/invoices # Delete a discount coupon. Source: https://docs.outseta.com/api-reference/billing/delete-a-discount-coupon /api-reference/openapi.json delete /api/v1/billing/discountcoupons/{discountCouponUid} # Delete a plan. Source: https://docs.outseta.com/api-reference/billing/delete-a-plan /api-reference/openapi.json delete /api/v1/billing/plans/{planUid} # Delete a plan family. Source: https://docs.outseta.com/api-reference/billing/delete-a-plan-family /api-reference/openapi.json delete /api/v1/billing/planfamilies/{planFamilyUid} # Delete a subscription. Source: https://docs.outseta.com/api-reference/billing/delete-a-subscription /api-reference/openapi.json delete /api/v1/billing/subscriptions/{subscriptionUid} Only a future-dated subscription can be deleted; the current subscription on an account cannot be removed this way. # Delete an invoice. Source: https://docs.outseta.com/api-reference/billing/delete-an-invoice /api-reference/openapi.json delete /api/v1/billing/invoices/{invoiceUid} # Email an invoice to the account's billing contact. Source: https://docs.outseta.com/api-reference/billing/email-an-invoice-to-the-accounts-billing-contact /api-reference/openapi.json post /api/v1/billing/invoices/{invoiceUid}/sendinvoiceemail Optional query parameters: note - free-text note to include in the email body. bcc - comma-separated list of email addresses to BCC. # End an add-on on a subscription. Source: https://docs.outseta.com/api-reference/billing/end-an-add-on-on-a-subscription /api-reference/openapi.json put /api/v1/billing/subscriptionaddons/{subscriptionAddOnUid}/end Removes the add-on from the subscription going forward and returns the updated subscription. # Immediately ends an add-on. Source: https://docs.outseta.com/api-reference/billing/immediately-ends-an-add-on /api-reference/openapi.json put /api/v1/billing/subscriptionaddons/{subscriptionAddOnUid}/expire # Indicate that an upgrade of an add-on is required. Source: https://docs.outseta.com/api-reference/billing/indicate-that-an-upgrade-of-an-add-on-is-required /api-reference/openapi.json put /api/v1/billing/subscriptionaddons/{subscriptionAddOnUid}/setaddonupgraderequired When a subscription add-on is flagged, the next time the user authenticates the authentication widget will prompt the user to change their add-on. # Indicate that an upgrade of plan is required. Source: https://docs.outseta.com/api-reference/billing/indicate-that-an-upgrade-of-plan-is-required /api-reference/openapi.json put /api/v1/billing/subscriptions/{subscriptionUid}/setsubscriptionupgraderequired When a subscription is flagged, next time the user authenticates the authentication widget will prompt the user to change plan. # Preview the initial or renewal invoice for a hypothetical subscription. Source: https://docs.outseta.com/api-reference/billing/preview-the-initial-or-renewal-invoice-for-a-hypothetical-subscription /api-reference/openapi.json post /api/v1/billing/subscriptions/compute-charge-summary Returns an invoice object with information about the amount outstanding if an account were to register with this subscription. BillingRenewalTerm values: 1 = Monthly, 2 = Yearly, 3 = Quarterly, 4 = OneTime. Pass asOf=renewal to see the renewal invoice instead of the initial invoice. # Preview the invoice for a subscription change. Source: https://docs.outseta.com/api-reference/billing/preview-the-invoice-for-a-subscription-change /api-reference/openapi.json put /api/v1/billing/subscriptions/{subscriptionUid}/changesubscriptionpreview Returns an invoice object with information about the amount outstanding. This method does not commit the subscription change. # Preview the invoice for adding an add-on to a subscription. Source: https://docs.outseta.com/api-reference/billing/preview-the-invoice-for-adding-an-add-on-to-a-subscription /api-reference/openapi.json post /api/v1/billing/subscriptionaddons/addsubscriptionaddonpreview Returns an invoice object with information about the amount outstanding. This method does not commit the change. # Remove a discount from a subscription. Source: https://docs.outseta.com/api-reference/billing/remove-a-discount-from-a-subscription /api-reference/openapi.json delete /api/v1/billing/subscriptions/{subscriptionUid}/discounts/{discountUid} Expires the active discount coupon on the subscription as of now. # Retrieve a discount coupon. Source: https://docs.outseta.com/api-reference/billing/retrieve-a-discount-coupon /api-reference/openapi.json get /api/v1/billing/discountcoupons/{discountCouponUid} # Retrieve a discount coupon by code. Source: https://docs.outseta.com/api-reference/billing/retrieve-a-discount-coupon-by-code /api-reference/openapi.json get /api/v1/public/billing/discountcoupons/{code} Used during registration to confirm that a coupon code can still be applied to a plan. Returns the coupon when valid, 404 when no coupon matches the code, or a validation error when the coupon cannot be applied. # Retrieve a plan. Source: https://docs.outseta.com/api-reference/billing/retrieve-a-plan /api-reference/openapi.json get /api/v1/billing/plans/{planUid} # Retrieve a plan family. Source: https://docs.outseta.com/api-reference/billing/retrieve-a-plan-family /api-reference/openapi.json get /api/v1/billing/planfamilies/{planFamilyUid} # Retrieve a rendered PDF copy of an invoice. Source: https://docs.outseta.com/api-reference/billing/retrieve-a-rendered-pdf-copy-of-an-invoice /api-reference/openapi.json get /api/v1/billing/invoices/{invoiceUid}/pdf Response body is a binary PDF (Content-Type: application/pdf) served as an attachment named invoice-{Number}-{InvoiceDate}-{AccountName}.pdf. # Retrieve a subscription. Source: https://docs.outseta.com/api-reference/billing/retrieve-a-subscription /api-reference/openapi.json get /api/v1/billing/subscriptions/{subscriptionUid} # Retrieve a subscription add-on. Source: https://docs.outseta.com/api-reference/billing/retrieve-a-subscription-add-on /api-reference/openapi.json get /api/v1/billing/subscriptionaddons/{subscriptionAddOnUid} # Retrieve all discount coupons. Source: https://docs.outseta.com/api-reference/billing/retrieve-all-discount-coupons /api-reference/openapi.json get /api/v1/billing/discountcoupons # Retrieve all invoices. Source: https://docs.outseta.com/api-reference/billing/retrieve-all-invoices /api-reference/openapi.json get /api/v1/billing/invoices Admins and API key callers see every invoice. Non-admin users see only invoices belonging to the account they are the primary contact of. Pass excludeInvoiceUid as a query parameter to omit a specific invoice from the result set. # Retrieve all plan families. Source: https://docs.outseta.com/api-reference/billing/retrieve-all-plan-families /api-reference/openapi.json get /api/v1/billing/planfamilies # Retrieve all plans. Source: https://docs.outseta.com/api-reference/billing/retrieve-all-plans /api-reference/openapi.json get /api/v1/billing/plans # Retrieve all subscription add-ons. Source: https://docs.outseta.com/api-reference/billing/retrieve-all-subscription-add-ons /api-reference/openapi.json get /api/v1/billing/subscriptionaddons # Retrieve all subscriptions. Source: https://docs.outseta.com/api-reference/billing/retrieve-all-subscriptions /api-reference/openapi.json get /api/v1/billing/subscriptions Admins and API key callers see every subscription; non-admin users see only subscriptions on accounts they are related to. That scope is determined by the auth token and cannot be widened by the caller. Optionally pass Account.PersonAccount.Person.Uid as a query parameter to narrow the results to a specific person. # Retrieve all transactions. Source: https://docs.outseta.com/api-reference/billing/retrieve-all-transactions /api-reference/openapi.json get /api/v1/billing/transactions/{accountUid} Transactions for a given account, tied to accounts and invoices. BillingTransactionType: Invoice = 1, Payment = 2, Credit = 3, Refund = 4, Chargeback = 5. # Retrieve an invoice. Source: https://docs.outseta.com/api-reference/billing/retrieve-an-invoice /api-reference/openapi.json get /api/v1/billing/invoices/{invoiceUid} # Retrieve the associations between plans and add-ons. Source: https://docs.outseta.com/api-reference/billing/retrieve-the-associations-between-plans-and-add-ons /api-reference/openapi.json get /api/v1/billing/planaddons Standard filtering applies, so the associations of a single plan are retrieved with ?Plan.Uid={planUid} and those of a single add-on with ?AddOn.Uid={addOnUid}. A PlanAddOns collection nested inside a plan or an add-on holds at most 100 entries, so a plan with more add-ons than that is read in full through this endpoint, which is paginated and has no such maximum. # Retrieve the redemptions of a discount coupon. Source: https://docs.outseta.com/api-reference/billing/retrieve-the-redemptions-of-a-discount-coupon /api-reference/openapi.json get /api/v1/billing/discountcoupons/{discountCouponUid}/redemptions # Send the invoice paid receipt email to the account's billing contact. Source: https://docs.outseta.com/api-reference/billing/send-the-invoice-paid-receipt-email-to-the-accounts-billing-contact /api-reference/openapi.json post /api/v1/billing/invoices/{invoiceUid}/sendinvoicepaidemail Returns 400 Bad Request if the invoice is not in the Paid status. # Update a discount coupon. Source: https://docs.outseta.com/api-reference/billing/update-a-discount-coupon /api-reference/openapi.json put /api/v1/billing/discountcoupons/{discountCouponUid} # Update a plan. Source: https://docs.outseta.com/api-reference/billing/update-a-plan /api-reference/openapi.json put /api/v1/billing/plans/{planUid} # Update a plan family. Source: https://docs.outseta.com/api-reference/billing/update-a-plan-family /api-reference/openapi.json put /api/v1/billing/planfamilies/{planFamilyUid} # Update an ad-hoc (manually created) invoice. Source: https://docs.outseta.com/api-reference/billing/update-an-ad-hoc-manually-created-invoice /api-reference/openapi.json put /api/v1/billing/invoices/{invoiceUid} Only invoices created manually via the API or admin UI can be updated; invoices generated by a subscription's billing cycle are immutable and will return a validation error. # Update payment information for an account. Source: https://docs.outseta.com/api-reference/billing/update-payment-information-for-an-account /api-reference/openapi.json post /api/v1/billing/paymentinformation # Add a cancellation request to an account. Source: https://docs.outseta.com/api-reference/crm/add-a-cancellation-request-to-an-account /api-reference/openapi.json put /api/v1/crm/accounts/{accountUid}/cancel The account needs to be in subscribing stage. The stage will automatically change over to cancelling. If the account has a subscription attached to it then at the subscription renewal the subscription will end and the account will be automatically set to expired. # Add a new account. Source: https://docs.outseta.com/api-reference/crm/add-a-new-account /api-reference/openapi.json post /api/v1/crm/accounts To add an account with an existing person, the Account payload include something like this: { ... other Account properties ..., "PersonAccount": [ { "Person": { "Uid": [personUid] }, "IsPrimary": "true" } ] } # Add a new deal. Source: https://docs.outseta.com/api-reference/crm/add-a-new-deal /api-reference/openapi.json post /api/v1/crm/deals # Add a new person. Source: https://docs.outseta.com/api-reference/crm/add-a-new-person /api-reference/openapi.json post /api/v1/crm/people # Add a person to an existing account. Source: https://docs.outseta.com/api-reference/crm/add-a-person-to-an-existing-account /api-reference/openapi.json post /api/v1/crm/accounts/{accountUid}/memberships Add a person to an existing account. Set sendWelcomeEmail=true to send a welcome email to the person added. # Add tags to a record. Source: https://docs.outseta.com/api-reference/crm/add-tags-to-a-record /api-reference/openapi.json post /api/v1/crm/segments/{entityUid}/tags Send the uids of the tags to add. Tags that the record already carries stay on it, and naming one of them again changes nothing, so the same request is safe to repeat. To replace the whole set instead, use PUT on this same path. A tag belongs to one entity type, so use tags whose EntityType matches this record. List them with GET /attribute/tags. A uid in the list that names no tag is skipped. # Delete a deal. Source: https://docs.outseta.com/api-reference/crm/delete-a-deal /api-reference/openapi.json delete /api/v1/crm/deals/{dealUid} # Delete a person record. Source: https://docs.outseta.com/api-reference/crm/delete-a-person-record /api-reference/openapi.json delete /api/v1/crm/people/{personUid} # Delete an account record. Source: https://docs.outseta.com/api-reference/crm/delete-an-account-record /api-reference/openapi.json delete /api/v1/crm/accounts/{accountUid} # Extend the date that a trial subscription expires. Source: https://docs.outseta.com/api-reference/crm/extend-the-date-that-a-trial-subscription-expires /api-reference/openapi.json put /api/v1/crm/accounts/{accountUid}/extend-trial # Initiate the forgot password flow. Source: https://docs.outseta.com/api-reference/crm/initiate-the-forgot-password-flow /api-reference/openapi.json post /api/v1/crm/people/forgotPassword Sends an email to the user with a link to a page where they can reset their password. The reset password token in the link is valid for 30 minutes. # Regenerate 2FA recovery codes for a user. Source: https://docs.outseta.com/api-reference/crm/regenerate-2fa-recovery-codes-for-a-user /api-reference/openapi.json put /api/v1/crm/people/{personUid}/regenerateTwoFactorRecoveryCodes Use this when a user is locked out of their authenticator. All prior recovery codes are invalidated. Existing TOTP/Email mechanisms are intentionally left in place — the admin returns the new codes to the user out of band, the user logs in with one, then re-enrolls their device. Mirrors the temporary-password flow at SetTemporaryPassword. # Register a new account. Source: https://docs.outseta.com/api-reference/crm/register-a-new-account /api-reference/openapi.json post /api/v1/crm/registrations This is the same endpoint the sign up embed uses to create accounts. At a minimum you must pass one Primary Contact with an Email address and one Subscription record with a reference to a Plan. Other fields (e.g. Account Name, Billing Address, Payment Information, etc.) can be passed as desired. A confirmation email will be sent to the user unless you've specifically toggled this option off on the AUTH > SIGN UP AND LOGIN page. # Remove a person from an account. Source: https://docs.outseta.com/api-reference/crm/remove-a-person-from-an-account /api-reference/openapi.json delete /api/v1/crm/accounts/{accountUid}/memberships/{membershipUid} Note that you cannot remove the primary contact of an account. # Remove a previous cancellation request from an account. Source: https://docs.outseta.com/api-reference/crm/remove-a-previous-cancellation-request-from-an-account /api-reference/openapi.json put /api/v1/crm/accounts/{accountUid}/remove-cancellation # Remove one tag from a record. Source: https://docs.outseta.com/api-reference/crm/remove-one-tag-from-a-record /api-reference/openapi.json delete /api/v1/crm/segments/{entityUid}/tags/{tagUid} The tag itself is kept and stays available for other records. If the record does not carry the tag, nothing changes and the call still succeeds. # Replace the tags on a record. Source: https://docs.outseta.com/api-reference/crm/replace-the-tags-on-a-record /api-reference/openapi.json put /api/v1/crm/segments/{entityUid}/tags Send the full set of tags the record must end with. A tag that the list leaves out is taken off the record, and one that the list names is added. Send an empty list to take every tag off. To add tags without disturbing the others, use POST on this same path. A tag belongs to one entity type, so use tags whose EntityType matches this record. List them with GET /attribute/tags. A uid in the list that names no tag is skipped. # Request a passwordless magic link to sign in. Source: https://docs.outseta.com/api-reference/crm/request-a-passwordless-magic-link-to-sign-in /api-reference/openapi.json post /api/v1/crm/people/requestMagicLink Sends an email containing a single-use, time-limited link that signs the recipient in without a password. Always responds 200 regardless of whether the email matches a known user or whether the feature is enabled, so the endpoint cannot be used to enumerate accounts. # Retrieve a deal. Source: https://docs.outseta.com/api-reference/crm/retrieve-a-deal /api-reference/openapi.json get /api/v1/crm/deals/{dealUid} # Retrieve a person. Source: https://docs.outseta.com/api-reference/crm/retrieve-a-person /api-reference/openapi.json get /api/v1/crm/people/{personUid} # Retrieve all accounts. Source: https://docs.outseta.com/api-reference/crm/retrieve-all-accounts /api-reference/openapi.json get /api/v1/crm/accounts Optionally filtered by segment (segmentUid) or search query (q). # Retrieve all deals. Source: https://docs.outseta.com/api-reference/crm/retrieve-all-deals /api-reference/openapi.json get /api/v1/crm/deals Returns the deals associated with your account. # Retrieve all people. Source: https://docs.outseta.com/api-reference/crm/retrieve-all-people /api-reference/openapi.json get /api/v1/crm/people Returns the people associated with your account. # Retrieve an account. Source: https://docs.outseta.com/api-reference/crm/retrieve-an-account /api-reference/openapi.json get /api/v1/crm/accounts/{accountUid} # Retrieve the tags on a record. Source: https://docs.outseta.com/api-reference/crm/retrieve-the-tags-on-a-record /api-reference/openapi.json get /api/v1/crm/segments/{entityUid}/tags Returns the tags themselves, not the links that hold them. The same tags are also available on the record: ask for them with the fields parameter, for example fields=Uid,Tags.Uid,Tags.Name,Tags.TagColor. Tags cost an extra query, so the record leaves them out unless fields names Tags or is a plain wildcard. # Send a confirmation email to people on an account. Source: https://docs.outseta.com/api-reference/crm/send-a-confirmation-email-to-people-on-an-account /api-reference/openapi.json put /api/v1/crm/accounts/{accountUid}/send-confirmation-email Pass personUid as a query parameter to send to a specific person, or personUid=* to send to all people on the account. If no personUid is provided, the email is sent to the primary contact. # Set a temporary password for a user. Source: https://docs.outseta.com/api-reference/crm/set-a-temporary-password-for-a-user /api-reference/openapi.json put /api/v1/crm/people/{personUid}/setTemporaryPassword The user needs to update the password with the next login. # Update a deal. Source: https://docs.outseta.com/api-reference/crm/update-a-deal /api-reference/openapi.json put /api/v1/crm/deals/{dealUid} # Update a person record. Source: https://docs.outseta.com/api-reference/crm/update-a-person-record /api-reference/openapi.json put /api/v1/crm/people/{personUid} You can update one or multiple properties on the object. Any property that you include in the json schema will be updated. To update custom properties just include them in the same way that they are included when you do a get on the object. # Update account information. Source: https://docs.outseta.com/api-reference/crm/update-account-information /api-reference/openapi.json put /api/v1/crm/accounts/{accountUid} You can update one or multiple properties on the object. Any property that you include in the json schema will be updated. To update custom properties just include them in the same way that they are included when you do a get on the object. # Update an account membership. Source: https://docs.outseta.com/api-reference/crm/update-an-account-membership /api-reference/openapi.json put /api/v1/crm/accounts/{accountUid}/memberships/{membershipUid} Update the membership that links a person to an account — for example, to make a different person the account's primary contact. The membershipUid identifies which membership to update; send the changed PersonAccount fields (such as IsPrimary) in the request body. # Add a message to a drip campaign. Source: https://docs.outseta.com/api-reference/email/add-a-message-to-a-drip-campaign /api-reference/openapi.json post /api/v1/email/campaigns/drips/{dripCampaignUid}/messages Adding a message deactivates the drip campaign so its schedule can be reviewed before it resumes sending. Use DelayInHours to control how long after the trigger the message is sent. # Add tags to a record. Source: https://docs.outseta.com/api-reference/email/add-tags-to-a-record /api-reference/openapi.json post /api/v1/email/campaigns/broadcasts/{entityUid}/tags Send the uids of the tags to add. Tags that the record already carries stay on it, and naming one of them again changes nothing, so the same request is safe to repeat. To replace the whole set instead, use PUT on this same path. A tag belongs to one entity type, so use tags whose EntityType matches this record. List them with GET /attribute/tags. A uid in the list that names no tag is skipped. # Archive a broadcast. Source: https://docs.outseta.com/api-reference/email/archive-a-broadcast /api-reference/openapi.json post /api/v1/email/campaigns/broadcasts/{broadcastCampaignUid}/archive Archived broadcasts are excluded from the default list results. # Create a new broadcast. Source: https://docs.outseta.com/api-reference/email/create-a-new-broadcast /api-reference/openapi.json post /api/v1/email/campaigns/broadcasts To copy an existing broadcast, retrieve it and pass its data as the request body — the Uid, SendDateTime, and message counts are automatically reset. A new broadcast is always created as a Draft; schedule it by updating it with a SendDateTime (see the update endpoint). Specify who the broadcast is sent to with EmailListUids and/or SegmentUids: EmailListUids is an array of email list Uids (from GET /api/v1/email/lists) and SegmentUids is an array of segment Uids (from GET /api/v1/crm/segments). These are the recommended way to set recipients — they are merged into the underlying RecipientData for you, so callers (including LLM tools) do not need to build that structure by hand; unknown Uids are rejected. RecipientData may still be supplied directly (a JSON string of the form {"BroadcastRecipientsEmailLists":[{"Uid":"..."}],"BroadcastRecipientsSegments":[{"Uid":"..."}]}); when both are present they are merged. Message.Body is rendered as a Liquid template, so it may include merge tags such as {{ Person.FirstName }}; unknown {{ }} tokens render as empty text. An inline-styled HTML fragment is recommended. Message.Design (the drag-and-drop editor state) is optional — when omitted it is derived automatically, so callers (including LLM tools) do not need to understand it. Use Message.PreviewText for inbox preview text rather than an in-body preheader. The shape of the Body markup decides how editable the broadcast is in the app. Prose (headings, paragraphs, lists, links, emphasis, images, inline spans) goes into a text block, which the author edits on the editor canvas with the formatting toolbar and the merge-tag menu. Structural markup (tables, an embedded style block, document scaffolding) goes into an HTML block instead, because only that block renders such markup verbatim, and it is edited as raw HTML. Send prose when the email must stay easy to edit visually. The first save in the editor also replaces Body with the editor's export of the design, so this choice decides the markup that is sent from then on. When Body is a content fragment with no Design, it is composed into the account's API email layout — a branded header and footer that includes the unsubscribe and manage-subscriptions links — and the composed result is what is sent and opened in the editor. Do not add your own unsubscribe link in this case; the layout provides one. The layout is editable in the app; TemplateUid selects a specific layout template when the account has more than one. The layout is NOT applied when a Design is supplied or when the body is a complex full HTML document (Outlook conditional comments, stylesheet links) — in those cases the body is sent exactly as supplied, and you must include a visible unsubscribe link in it yourself: add {{ UnsubscribeLink }} (a ready-made anchor) or {{ UnsubscribeUrl }} (the raw URL) where you want it. Its presence is not validated. A one-click List-Unsubscribe header is always added, but most anti-spam laws (e.g. CAN-SPAM) also require a visible unsubscribe link in the body. # Create a new drip campaign. Source: https://docs.outseta.com/api-reference/email/create-a-new-drip-campaign /api-reference/openapi.json post /api/v1/email/campaigns/drips To copy an existing drip campaign, retrieve it and pass its data as the request body — the Uid and per-message counts are automatically reset. Messages can be supplied inline via DripCampaignMessages, or added later with the messages endpoint. Each inline message's Name defaults to its position (e.g. "Message 1") when omitted. # Create an email list. Source: https://docs.outseta.com/api-reference/email/create-an-email-list /api-reference/openapi.json post /api/v1/email/lists Name is required and must be unique. Set RequiresDoubleOptIn to true to require new subscribers to confirm their subscription. WelcomeSubject and WelcomeBody configure an optional welcome email; use WelcomeFromName and WelcomeFromEmail to set its sender. # Delete a broadcast. Source: https://docs.outseta.com/api-reference/email/delete-a-broadcast /api-reference/openapi.json delete /api/v1/email/campaigns/broadcasts/{broadcastCampaignUid} Only broadcasts in Draft or Pending status can be deleted. Broadcasts that have been processed should be archived instead. # Delete a drip campaign. Source: https://docs.outseta.com/api-reference/email/delete-a-drip-campaign /api-reference/openapi.json delete /api/v1/email/campaigns/drips/{dripCampaignUid} # Delete a message from a drip campaign. Source: https://docs.outseta.com/api-reference/email/delete-a-message-from-a-drip-campaign /api-reference/openapi.json delete /api/v1/email/campaigns/drips/{dripCampaignUid}/messages/{dripCampaignMessageUid} Deleting a message deactivates the drip campaign (like adding a message) so its schedule can be reviewed before it resumes. Reactivate the campaign to resume sending. # Delete an email list. Source: https://docs.outseta.com/api-reference/email/delete-an-email-list /api-reference/openapi.json delete /api/v1/email/lists/{emailListUid} Deleting a list also removes all of its subscriptions. # Remove a subscriber from an email list. Source: https://docs.outseta.com/api-reference/email/remove-a-subscriber-from-an-email-list /api-reference/openapi.json delete /api/v1/email/lists/{emailListUid}/subscriptions/{subscriptionUid} # Remove one tag from a record. Source: https://docs.outseta.com/api-reference/email/remove-one-tag-from-a-record /api-reference/openapi.json delete /api/v1/email/campaigns/broadcasts/{entityUid}/tags/{tagUid} The tag itself is kept and stays available for other records. If the record does not carry the tag, nothing changes and the call still succeeds. # Replace the tags on a record. Source: https://docs.outseta.com/api-reference/email/replace-the-tags-on-a-record /api-reference/openapi.json put /api/v1/email/campaigns/broadcasts/{entityUid}/tags Send the full set of tags the record must end with. A tag that the list leaves out is taken off the record, and one that the list names is added. Send an empty list to take every tag off. To add tags without disturbing the others, use POST on this same path. A tag belongs to one entity type, so use tags whose EntityType matches this record. List them with GET /attribute/tags. A uid in the list that names no tag is skipped. # Retrieve a broadcast. Source: https://docs.outseta.com/api-reference/email/retrieve-a-broadcast /api-reference/openapi.json get /api/v1/email/campaigns/broadcasts/{broadcastCampaignUid} # Retrieve a drip campaign. Source: https://docs.outseta.com/api-reference/email/retrieve-a-drip-campaign /api-reference/openapi.json get /api/v1/email/campaigns/drips/{dripCampaignUid} # Retrieve a message from a drip campaign. Source: https://docs.outseta.com/api-reference/email/retrieve-a-message-from-a-drip-campaign /api-reference/openapi.json get /api/v1/email/campaigns/drips/{dripCampaignUid}/messages/{dripCampaignMessageUid} # Retrieve all broadcasts. Source: https://docs.outseta.com/api-reference/email/retrieve-all-broadcasts /api-reference/openapi.json get /api/v1/email/campaigns/broadcasts Archived broadcasts are excluded. # Retrieve all drip campaigns. Source: https://docs.outseta.com/api-reference/email/retrieve-all-drip-campaigns /api-reference/openapi.json get /api/v1/email/campaigns/drips # Retrieve all email lists. Source: https://docs.outseta.com/api-reference/email/retrieve-all-email-lists /api-reference/openapi.json get /api/v1/email/lists # Retrieve all subscribers to an email list. Source: https://docs.outseta.com/api-reference/email/retrieve-all-subscribers-to-an-email-list /api-reference/openapi.json get /api/v1/email/lists/{emailListUid}/subscriptions # Retrieve an email list. Source: https://docs.outseta.com/api-reference/email/retrieve-an-email-list /api-reference/openapi.json get /api/v1/email/lists/{emailListUid} # Retrieve the tags on a record. Source: https://docs.outseta.com/api-reference/email/retrieve-the-tags-on-a-record /api-reference/openapi.json get /api/v1/email/campaigns/broadcasts/{entityUid}/tags Returns the tags themselves, not the links that hold them. The same tags are also available on the record: ask for them with the fields parameter, for example fields=Uid,Tags.Uid,Tags.Name,Tags.TagColor. Tags cost an extra query, so the record leaves them out unless fields names Tags or is a plain wildcard. # Send a test email for a broadcast. Source: https://docs.outseta.com/api-reference/email/send-a-test-email-for-a-broadcast /api-reference/openapi.json post /api/v1/email/campaigns/broadcasts/sendtestemail Sends to the logged-in user and optionally to additional recipients. Additional recipients are specified as a list of person Uids and must belong to the same account as the logged-in user. # Send a test email for a drip campaign. Source: https://docs.outseta.com/api-reference/email/send-a-test-email-for-a-drip-campaign /api-reference/openapi.json post /api/v1/email/campaigns/drips/sendtestemail Sends the drip campaign to the logged-in user and optionally to additional recipients. Additional recipients are specified as a list of person Uids and must belong to the same account as the logged-in user. Sending is skipped when the account is restricted due to unpaid invoices. # Subscribe a person to an email list. Source: https://docs.outseta.com/api-reference/email/subscribe-a-person-to-an-email-list /api-reference/openapi.json post /api/v1/email/lists/{emailListUid}/subscriptions To subscribe a new person, pass a Person object with an Email address. To subscribe an existing person, pass a Person object with a Uid. The SendWelcomeEmail property determines if the person is sent a welcome email and defaults to false. # Unschedule a broadcast. Source: https://docs.outseta.com/api-reference/email/unschedule-a-broadcast /api-reference/openapi.json post /api/v1/email/campaigns/broadcasts/{broadcastCampaignUid}/unschedule Unschedules a pending broadcast, reverting its status to Draft. # Update a broadcast. Source: https://docs.outseta.com/api-reference/email/update-a-broadcast /api-reference/openapi.json put /api/v1/email/campaigns/broadcasts/{broadcastCampaignUid} Setting SendDateTime to a future UTC date schedules the broadcast for sending and its status changes to Pending. An account may only have 5 broadcasts scheduled or sending at one time; scheduling beyond that is rejected until one finishes sending or is unscheduled. There is no limit on the number of drafts. Clearing SendDateTime unschedules the broadcast. Recipients can be added with EmailListUids and SegmentUids (see the create endpoint): on update these are merged onto the broadcast's existing recipients and only ever add — to remove recipients or replace the set, send RecipientData directly. When changing Message.Body, omit Message.Design: it is regenerated from the new Body so the drag-and-drop editor stays in sync. Sending a Design that was captured from an earlier response alongside an edited Body would otherwise keep the stale design. A body that was composed into the API email layout keeps the layout on such updates without duplicating it — its content is re-composed into the layout — and a bare fragment is composed like on create. See the create endpoint for how Body is rendered (Liquid), when the layout applies, and the unsubscribe-token expectation when it does not. # Update a drip campaign. Source: https://docs.outseta.com/api-reference/email/update-a-drip-campaign /api-reference/openapi.json put /api/v1/email/campaigns/drips/{dripCampaignUid} Activating a drip campaign (setting IsActive) begins sending its messages to members. StartDripToExistingMembers controls whether members already in the campaign receive the messages or only members added going forward. # Update a message in a drip campaign. Source: https://docs.outseta.com/api-reference/email/update-a-message-in-a-drip-campaign /api-reference/openapi.json put /api/v1/email/campaigns/drips/{dripCampaignUid}/messages/{dripCampaignMessageUid} Changing DelayInHours on an active drip campaign reschedules the drip for its existing members. The DripCampaign Uid on the body, if supplied, must match the dripCampaignUid in the URL, and the message Uid on the body must match the dripCampaignMessageUid in the URL. # Update an email list. Source: https://docs.outseta.com/api-reference/email/update-an-email-list /api-reference/openapi.json put /api/v1/email/lists/{emailListUid} The Uid may be omitted from the request body. If supplied, it must match the Uid in the URL. # Begin email enrollment during a forced-2FA login. Source: https://docs.outseta.com/api-reference/public/begin-email-enrollment-during-a-forced-2fa-login /api-reference/openapi.json post /api/v1/tokens/two-factor/enroll/email/begin Call this when `POST /api/v1/tokens` returned `two_factor_enrollment_required` and the user chooses email. Post the enrollment token from that response: ```json { "enrollment_token": "eyJ..." } ``` A verification code is emailed to the user and a challenge is returned: ```json { "challenge_token": "eyJ...", "mechanism": "Email", "masked_destination": "b***@outseta.com", "expires_in": 600 } ``` Confirm the code via `POST /api/v1/tokens/two-factor/enroll/email/confirm`. Returns `401` if the enrollment token is invalid/expired and `403` if forced enrollment does not apply to this user. Rate limited to 5 requests per minute (`429`). # Complete login when user has two-factor authentication enabled. Source: https://docs.outseta.com/api-reference/public/complete-login-when-user-has-two-factor-authentication-enabled /api-reference/openapi.json post /api/v1/tokens/two-factor Call this after `POST /api/v1/tokens` returns `two_factor_required`. Post the challenge token from that response together with the user's one-time code (the emailed code, or the current code from their authenticator app): ```json { "challenge_token": "eyJ...", "code": "123456" } ``` On success the response is `200` with the final access token, in the same shape as `POST /api/v1/tokens`: ```json { "access_token": "eyJ...", "refresh_token": "...", "token_type": "Bearer", "expires_in": 31536000 } ``` An incorrect code returns `400` (`invalid_grant`). A code has at most five attempts before the challenge locks. An expired challenge returns `410` (`challenge_expired`) — restart at `POST /api/v1/tokens`. The endpoint is rate limited to 10 requests per minute (`429`). # Complete login with a two-factor recovery code. Source: https://docs.outseta.com/api-reference/public/complete-login-with-a-two-factor-recovery-code /api-reference/openapi.json post /api/v1/tokens/two-factor/recovery A fallback for users who cannot produce their primary code but still have a recovery code on file (see `recovery_codes_available` on the login response). Post the challenge token together with one recovery code: ```json { "challenge_token": "eyJ...", "recovery_code": "abcd-efgh-ijkl" } ``` On success the response is `200` with the final access token, in the same shape as `POST /api/v1/tokens`. Each recovery code is single-use. An incorrect code returns `400` (`invalid_grant`); an expired challenge returns `410` (`challenge_expired`). Rate limited to 10 requests per minute (`429`). Used by the embed login widget; the hosted Razor flow has its own equivalent action on the AuthenticationController. # Confirm authenticator-app (TOTP) enrollment and complete a forced-2FA login. Source: https://docs.outseta.com/api-reference/public/confirm-authenticator-app-totp-enrollment-and-complete-a-forced-2fa-login /api-reference/openapi.json post /api/v1/tokens/two-factor/enroll/totp/confirm Post the enrollment token (from `POST /api/v1/tokens`), the challenge token (from `.../enroll/totp/begin`), and the current code from the user's authenticator app: ```json { "enrollment_token": "eyJ...", "challenge_token": "eyJ...", "code": "123456" } ``` On success authenticator-app 2FA is enabled and login completes — the response carries the final access token plus the user's one-time recovery codes: ```json { "confirmed": true, "recovery_codes": ["abcd-efgh-ijkl", "..."], "access_token": "eyJ...", "token_type": "Bearer", "expires_in": 31536000 } ``` Show the `recovery_codes` to the user once — they are not returned again. An incorrect code returns `400` (`invalid_grant`); an expired challenge returns `410` (`challenge_expired`). Rate limited to 10 requests per minute (`429`). # Confirm email enrollment and complete a forced-2FA login. Source: https://docs.outseta.com/api-reference/public/confirm-email-enrollment-and-complete-a-forced-2fa-login /api-reference/openapi.json post /api/v1/tokens/two-factor/enroll/email/confirm Post the enrollment token (from `POST /api/v1/tokens`), the challenge token (from `.../enroll/email/begin`), and the emailed code: ```json { "enrollment_token": "eyJ...", "challenge_token": "eyJ...", "code": "123456" } ``` On success email 2FA is enabled and login completes — the response carries the final access token plus the user's one-time recovery codes: ```json { "confirmed": true, "recovery_codes": ["abcd-efgh-ijkl", "..."], "access_token": "eyJ...", "token_type": "Bearer", "expires_in": 31536000 } ``` Show the `recovery_codes` to the user once — they are not returned again. An incorrect code returns `400` (`invalid_grant`); an expired challenge returns `410` (`challenge_expired`). Rate limited to 10 requests per minute (`429`). # Exchange a magic-link token for an access token (passwordless login). Source: https://docs.outseta.com/api-reference/public/exchange-a-magic-link-token-for-an-access-token-passwordless-login /api-reference/openapi.json post /api/v1/tokens/magic-link Call this with the magicToken carried by the link from a "magic link" email (requested via POST /api/v1/crm/people/requestMagicLink): ```json { "magic_token": "eyJ..." } ``` The link proves control of the email inbox, which satisfies the first factor. The response then matches POST /api/v1/tokens: - 200 with an access token when no further factor is required; - 202 with a two_factor_required challenge when the user has a non-email second factor (e.g. an authenticator app) that must still be cleared via POST /api/v1/tokens/two-factor. Email is never offered as that second factor — it was already the first. An invalid, expired, already-used token (or a tenant without magic-link login enabled) returns 400 (invalid_grant). # Log a user in. Source: https://docs.outseta.com/api-reference/public/log-a-user-in /api-reference/openapi.json post /api/v1/tokens Authenticates a user and returns a JWT access token (plus a refresh token). Post a JSON body with the user's credentials: ```json { "username": "user@example.com", "password": "their-password" } ``` On success the response is `200` with an access token and refresh token: ```json { "access_token": "eyJ...", "refresh_token": "...", "token_type": "Bearer", "expires_in": 31536000 } ``` **Two-factor authentication.** If the user has a verified 2FA method, the password alone is not enough. After verifying the password this endpoint instead returns `202 Accepted` with a challenge that must be satisfied via `POST /api/v1/tokens/two-factor`: ```json { "two_factor_required": true, "challenge_token": "eyJ...", "mechanism": "Totp", "masked_destination": "", "expires_in": 600, "available_mechanisms": ["Totp", "Email"], "recovery_codes_available": true } ``` `mechanism` is the method this challenge targets. When it is `Email`, a one-time code has already been emailed to the user (see `masked_destination`); when it is `Totp`, the user reads the current code from their authenticator app and nothing is sent. `available_mechanisms` lists every method the user has enrolled so a client can offer a switch via `POST /api/v1/tokens/two-factor/switch-mechanism`. If the tenant forces 2FA but the user has not enrolled yet, the `202` body instead contains `"two_factor_enrollment_required": true` with a `challenge_token` to drive the mid-login enrollment endpoints. Invalid credentials return `400` with a body of `invalid_grant`. # Post apiv1tokenstwo factorenrolltotpbegin Source: https://docs.outseta.com/api-reference/public/post-apiv1tokenstwo-factorenrolltotpbegin /api-reference/openapi.json post /api/v1/tokens/two-factor/enroll/totp/begin # Publicly subscribe a person to an email list. Source: https://docs.outseta.com/api-reference/public/publicly-subscribe-a-person-to-an-email-list /api-reference/openapi.json post /api/v1/public/email/lists/{emailListUid}/subscriptions This endpoint does not require authentication. The email list must be public, and the subscription is subject to bot protection and the list's double opt-in settings. # Re-send the one-time code for an in-progress email two-factor challenge. Source: https://docs.outseta.com/api-reference/public/re-send-the-one-time-code-for-an-in-progress-email-two-factor-challenge /api-reference/openapi.json post /api/v1/tokens/two-factor/resend Post the challenge token from the original `POST /api/v1/tokens` response: ```json { "challenge_token": "eyJ..." } ``` A fresh code is emailed and a new challenge is returned (superseding the previous one), in the same shape as the `202` from `POST /api/v1/tokens` minus `two_factor_required`. Only `Email` challenges can be resent — there is nothing to resend for `Totp` (the authenticator app generates codes locally), so a `Totp` challenge returns `400` with a body of `not_supported`. Rate limited to 3 requests per minute (`429`). # Switch an in-progress login challenge to a different enrolled mechanism. Source: https://docs.outseta.com/api-reference/public/switch-an-in-progress-login-challenge-to-a-different-enrolled-mechanism /api-reference/openapi.json post /api/v1/tokens/two-factor/switch-mechanism When a user has more than one method enrolled (see `available_mechanisms` on the login response) they can switch the active challenge — for example from `Totp` to `Email` when they have lost access to their authenticator. Post the current challenge token and the desired mechanism: ```json { "challenge_token": "eyJ...", "mechanism": "Email" } ``` A fresh challenge for that mechanism is returned (and, for `Email`, a code is sent), in the same shape as the `202` from `POST /api/v1/tokens` minus `two_factor_required`. An unrecognized mechanism returns `400` (`invalid_mechanism`); a mechanism the user has not enrolled returns `400` (`not_enrolled`). Rate limited to 5 requests per minute (`429`). # Register with a free trial Source: https://docs.outseta.com/api-reference/registration/register-free-trial Create a new account that begins on a free trial, with no payment required up front. This variation of [Register a new account](/api-reference/crm/register-a-new-account) starts the account on a trialing subscription so the user can get in without entering payment details. ## When to use this Use this flow for self-serve trial sign-ups. The account is created in a trialing state and converts to a paid subscription when the trial ends or payment information is added. ## Request Send the same `Account` body as [Register a new account](/api-reference/crm/register-a-new-account), referencing the trial-eligible `Plan` and omitting `PaymentInformation`. ```json theme={null} { "Name": "ACME, LLC", "PersonAccount": [ { "IsPrimary": true, "Person": { "Email": "jdoe@domain.com" } } ], "Subscriptions": [ { "BillingRenewalTerm": 2, "Plan": { "Uid": "nB8kRZ3w" } } ] } ``` > [!NOTE] > > **The trial length comes from the plan.** Outseta sets the trial end date from > the trial period configured on the referenced `Plan` — a `RenewalDate` sent in > the registration body is *not* honored at sign-up. To change when a trial ends, > use [Extend a > trial](/api-reference/crm/extend-the-date-that-a-trial-subscription-expires) after > the account is created. > > `BillingRenewalTerm` is the post-trial billing cadence: `1` Monthly, `2` Yearly, > `3` Quarterly, `4` One-time. See [Register a new > account](/api-reference/crm/register-a-new-account) for the full `Account` schema > and the interactive playground. ## Related * [Register a new account](/api-reference/crm/register-a-new-account) * [Register with a paid plan](/api-reference/registration/register-with-plan) # Register with a paid plan Source: https://docs.outseta.com/api-reference/registration/register-with-plan Create a new account on a specific plan and start a subscription during registration. This variation of [Register a new account](/api-reference/crm/register-a-new-account) creates the account, person, and subscription in a single call by supplying plan and billing details in the registration payload. ## When to use this Use this flow when a visitor signs up directly onto a paid plan from your own checkout, rather than starting a free trial or being added manually. ## Request Send the same `Account` body as [Register a new account](/api-reference/crm/register-a-new-account), adding the subscription's paid `Plan` and a `PaymentInformation` object. Payment details are supplied as a **token** from your payment gateway — the API never accepts a raw card number. ```json theme={null} { "Name": "ACME, LLC", "PersonAccount": [ { "IsPrimary": true, "Person": { "Email": "jdoe@domain.com" } } ], "Subscriptions": [ { "BillingRenewalTerm": 2, "Plan": { "Uid": "amRXjE9J" } } ], "BillingAddress": { "AddressLine1": "123 Main St", "City": "Burlington", "State": "VT", "PostalCode": "05401", "Country": "US" }, "PaymentInformation": { "NameOnCard": "Jane Doe", "PaymentToken": "tok_1A2b3C4d5E6f7G8h", "CardType": "Visa", "ExpirationMonth": "12", "ExpirationYear": "2027" } } ``` > [!NOTE] > > `PaymentToken` is a single-use token created by your payment provider's > client-side SDK (e.g. Stripe) — tokenize the card in the browser and send only > the resulting token. Depending on your billing gateway, registration may instead > return a hosted-checkout `RedirectUrl` to collect payment. > > `BillingRenewalTerm` is the billing cadence: `1` Monthly, `2` Yearly, `3` > Quarterly, `4` One-time. See [Register a new > account](/api-reference/crm/register-a-new-account) for the full `Account` schema > and the interactive playground. ## Related * [Register a new account](/api-reference/crm/register-a-new-account) * [Register with a free trial](/api-reference/registration/register-free-trial) # Add tags to a record. Source: https://docs.outseta.com/api-reference/support/add-tags-to-a-record /api-reference/openapi.json post /api/v1/support/articles/{entityUid}/tags Send the uids of the tags to add. Tags that the record already carries stay on it, and naming one of them again changes nothing, so the same request is safe to repeat. To replace the whole set instead, use PUT on this same path. A tag belongs to one entity type, so use tags whose EntityType matches this record. List them with GET /attribute/tags. A uid in the list that names no tag is skipped. # Adds a case into the support system. Source: https://docs.outseta.com/api-reference/support/adds-a-case-into-the-support-system /api-reference/openapi.json post /api/v1/support/cases # Adds a reply from an agent to a support case. Source: https://docs.outseta.com/api-reference/support/adds-a-reply-from-an-agent-to-a-support-case /api-reference/openapi.json post /api/v1/support/cases/{caseUid}/replies # Adds a response to the case from the person that opened the case. Source: https://docs.outseta.com/api-reference/support/adds-a-response-to-the-case-from-the-person-that-opened-the-case /api-reference/openapi.json post /api/v1/support/cases/{caseUid}/clientresponse/{comment} # Create a knowledge base article. Source: https://docs.outseta.com/api-reference/support/create-a-knowledge-base-article /api-reference/openapi.json post /api/v1/support/articles # Permanently delete a support ticket. Source: https://docs.outseta.com/api-reference/support/permanently-delete-a-support-ticket /api-reference/openapi.json delete /api/v1/support/cases/{caseUid} The ticket is deleted together with all its replies, notes, tags and attachments. This cannot be undone. The ticket and its history are gone when the request returns. Its attachment files, its search entry, and the logs of the emails and activities that relate to it are removed in the background shortly after. # Remove one tag from a record. Source: https://docs.outseta.com/api-reference/support/remove-one-tag-from-a-record /api-reference/openapi.json delete /api/v1/support/articles/{entityUid}/tags/{tagUid} The tag itself is kept and stays available for other records. If the record does not carry the tag, nothing changes and the call still succeeds. # Replace the tags on a record. Source: https://docs.outseta.com/api-reference/support/replace-the-tags-on-a-record /api-reference/openapi.json put /api/v1/support/articles/{entityUid}/tags Send the full set of tags the record must end with. A tag that the list leaves out is taken off the record, and one that the list names is added. Send an empty list to take every tag off. To add tags without disturbing the others, use POST on this same path. A tag belongs to one entity type, so use tags whose EntityType matches this record. List them with GET /attribute/tags. A uid in the list that names no tag is skipped. # Retrieve a case. Source: https://docs.outseta.com/api-reference/support/retrieve-a-case /api-reference/openapi.json get /api/v1/support/cases/{caseUid} # Retrieve a knowledge base article. Source: https://docs.outseta.com/api-reference/support/retrieve-a-knowledge-base-article /api-reference/openapi.json get /api/v1/support/articles/{articleUid} # Retrieve all cases. Source: https://docs.outseta.com/api-reference/support/retrieve-all-cases /api-reference/openapi.json get /api/v1/support/cases Optionally filtered by search string, tag, and/or assignment. Assigned cases can be filtered by passing in the AssignedToPersonClientIdentifier, which is the Uid of the person the case is assigned to. # Retrieve all knowledge base articles. Source: https://docs.outseta.com/api-reference/support/retrieve-all-knowledge-base-articles /api-reference/openapi.json get /api/v1/support/articles # Retrieve all knowledge base categories. Source: https://docs.outseta.com/api-reference/support/retrieve-all-knowledge-base-categories /api-reference/openapi.json get /api/v1/support/categories # Retrieve the tags on a record. Source: https://docs.outseta.com/api-reference/support/retrieve-the-tags-on-a-record /api-reference/openapi.json get /api/v1/support/articles/{entityUid}/tags Returns the tags themselves, not the links that hold them. The same tags are also available on the record: ask for them with the fields parameter, for example fields=Uid,Tags.Uid,Tags.Name,Tags.TagColor. Tags cost an extra query, so the record leaves them out unless fields names Tags or is a plain wildcard. # Update a support ticket. Source: https://docs.outseta.com/api-reference/support/update-a-support-ticket /api-reference/openapi.json put /api/v1/support/cases/{caseUid} The Uid in the URL identifies the ticket, and a Uid in the request body is ignored. Any property that the body does not contain keeps its current value, so a request can send only the properties that change. Tags are managed through the CaseTags collection. Send the full set of tags that the ticket must end with: - To keep a tag, include its entry with the CaseTag Uid that GET returned. - To add a tag, include an entry that has no Uid and a Tag that holds the tag's Uid. - To remove a tag, leave its entry out. - To remove all tags, send an empty array. If the body does not contain CaseTags, the current tags stay as they are. To read the current tags, request them with the fields parameter, for example fields=Uid,CaseTags.Uid,CaseTags.Tag.Uid,CaseTags.Tag.Name. To get the tags that are available for tickets, use GET /attribute/tags?entityType=Case. Case history is kept. Add replies and notes with their own endpoints. # Send an email template to a single person as a one-off email. Source: https://docs.outseta.com/api-reference/template/send-an-email-template-to-a-single-person-as-a-one-off-email /api-reference/openapi.json post /api/v1/templates/{templateUid}/send The email is merge-rendered for the person and sent immediately. No broadcast is created. People who have bounced, unsubscribed or reported spam are not sent the email. Only templates from Email > Email templates can be sent. The response holds the record of the send. Read the open and click analytics for it later from the emails endpoint for the template. The template and the recipient are left out of the response unless they are asked for, for example fields=*,Template.Uid,Recipient.Uid. # The one-off emails that were sent from any email template. Source: https://docs.outseta.com/api-reference/template/the-one-off-emails-that-were-sent-from-any-email-template /api-reference/openapi.json get /api/v1/templates/emails Filter with personUid to see what one person was sent, or with templateUid to restrict the results to a single template. # The one-off emails that were sent from this email template. Source: https://docs.outseta.com/api-reference/template/the-one-off-emails-that-were-sent-from-this-email-template /api-reference/openapi.json get /api/v1/templates/{templateUid}/emails Add personUid to the query string to see what one person was sent from this template. # Authentication Source: https://docs.outseta.com/essentials/authentication How to authenticate requests to the Outseta API. The Outseta API supports two authentication schemes. Pick the one that matches your use case. ## API key (server-to-server) Use API keys when calling the API from a backend you control. Each key has a paired secret — together they're sent in the `Authorization` header. ```http theme={null} Authorization: Outseta : ``` You can generate keys from the Outseta admin console under **Settings → API Keys**. > [!WARNING] > > Never embed an API key + secret in client-side code (browsers, mobile apps). Use bearer tokens for those flows. ## Bearer token (client-side) For client-side calls (e.g. a logged-in user fetching their own data), use a JWT access token issued by the Outseta auth flow. ```http theme={null} Authorization: bearer ``` Tokens are short-lived and should be refreshed using the standard OAuth refresh flow. ## Choosing between them | Use case | Scheme | | - | - | | Backend job, webhook handler, server-side integration | API key | | Logged-in browser/mobile session | Bearer token | | Public, unauthenticated endpoints (e.g. signup) | None | # Introduction Source: https://docs.outseta.com/index REST API reference for Outseta — auth, billing, user accounts, email, and support, all in one platform. > **[Auth](/api-reference/public/log-a-user-in)** > > Login and two-factor authentication flows. > **[Billing](/api-reference/billing/add-a-new-discount-coupon)** > > Subscriptions, plans, invoices, transactions, and usage. > **[CRM](/api-reference/crm/register-a-new-account)** > > Registration, accounts, people, deals, and custom attributes. > **[Email](/api-reference/email/retrieve-all-broadcasts)** > > Broadcasts and drip campaigns, plus email list subscriptions. > **[Support](/api-reference/support/retrieve-all-knowledge-base-articles)** > > Help desk cases, replies, and knowledge base articles. > **[Activity](/api-reference/activity/retrieve-all-activities)** > > Account, person, and deal activity, including custom events. The Outseta API is a standard REST service that returns JSON and is documented in OpenAPI 3. Every endpoint includes its request and response shapes and a live "Try it" playground. ## Base URL Outseta is multi-tenant — your API lives at your own subdomain: ``` https://{subdomain}.outseta.com ``` Replace `{subdomain}` with your Outseta account subdomain — the part before `.outseta.com` in your admin URL. In the "Try it" playground, set the editable `subdomain` field once and every request targets your account. ## Authentication Most endpoints require authentication. Server-to-server calls use an API key; logged-in browser/mobile sessions use a bearer token. See [Authentication](/essentials/authentication) for details and when to use each. ## Conventions * All requests are made over HTTPS. * Timestamps are ISO 8601 UTC. * Resource identifiers (`Uid`) are short opaque strings, not GUIDs. > [!NOTE] > > Some endpoints that return core CRM entities (accounts, people, subscriptions) > carry large, deeply nested response schemas, so their pages can take a moment > to render. ## Build with AI tools Prefer to let an AI agent do the work? Outseta ships a remote MCP server and an agent toolkit. > **[MCP server](/mcp-server)** > > Connect your agent to Outseta's remote MCP server to manage your account and analyze your business data directly. > **[Agent skills](/agent-skills)** > > Add the Outseta agent toolkit so your agent can wire Outseta into your app from a prompt. # MCP server Source: https://docs.outseta.com/mcp-server Connect your AI agent to Outseta with the remote MCP server — manage your account and analyze your business data directly. Skip the dashboard. With our remote MCP server, your agent can manage your Outseta account and analyze your business data directly. The server is available at: ``` https://agent.outseta.com/mcp ``` ## Install MCP server Pick your client below for setup instructions. **Claude Code** Add the MCP server using the command line: ```bash theme={null} claude mcp add --scope project --transport http outseta https://agent.outseta.com/mcp ``` Alternatively, add this configuration to `.mcp.json`: ```json theme={null} { "mcpServers": { "outseta": { "type": "http", "url": "https://agent.outseta.com/mcp" } } } ``` After configuring the MCP server, you need to authenticate. In a regular terminal (not the IDE extension) run: ```bash theme={null} claude /mcp ``` Select the `outseta` server, then **Authenticate** to begin the authentication flow. Need help? [View Claude Code docs](https://docs.claude.com/en/docs/claude-code/mcp) **Cursor** Add the MCP server using the command line: ```bash theme={null} cursor mcp add --transport http outseta https://agent.outseta.com/mcp ``` Alternatively, add this configuration to `.cursor/mcp.json` in your project (or `~/.cursor/mcp.json` for all projects): ```json theme={null} { "mcpServers": { "outseta": { "url": "https://agent.outseta.com/mcp" } } } ``` After configuring the MCP server, open **Settings → MCP** and click **Login** next to the `outseta` server to begin the authentication flow. Need help? [View Cursor docs](https://docs.cursor.com/context/model-context-protocol) **VS Code** Add the MCP server using the command line: ```bash theme={null} code --add-mcp '{"name":"outseta","type":"http","url":"https://agent.outseta.com/mcp"}' ``` Alternatively, add this configuration to `.vscode/mcp.json` in your project: ```json theme={null} { "servers": { "outseta": { "type": "http", "url": "https://agent.outseta.com/mcp" } } } ``` After configuring the MCP server, open the **MCP: List Servers** command, select `outseta`, and start it to begin the authentication flow. Need help? [View VS Code docs](https://code.visualstudio.com/docs/copilot/chat/mcp-servers) **Claude Desktop** Add this configuration to `claude_desktop_config.json` (**Settings → Developer → Edit Config**): ```json theme={null} { "mcpServers": { "outseta": { "type": "http", "url": "https://agent.outseta.com/mcp" } } } ``` After saving, restart Claude Desktop. It will prompt you to log in and grant access to begin the authentication flow. Need help? [View Claude Desktop docs](https://modelcontextprotocol.io/quickstart/user) **Windsurf** Add this configuration to `~/.codeium/windsurf/mcp_config.json`: ```json theme={null} { "mcpServers": { "outseta": { "serverUrl": "https://agent.outseta.com/mcp" } } } ``` After saving, open the Cascade panel, refresh your MCP servers, and click **Login** next to the `outseta` server to begin the authentication flow. Need help? [View Windsurf docs](https://docs.windsurf.com/windsurf/cascade/mcp) > [!NOTE] > > **Authentication** > > Some MCP clients will automatically prompt you to log in during setup, while others require the manual step above. Either way, a browser window opens where you can log in to your Outseta account and grant the MCP client access. > > No personal access token or API key is required — authentication is handled through your Outseta login.