> For the complete documentation index, see [llms.txt](https://docs.thewalletcrew.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.thewalletcrew.io/api-reference/tenant-configuration/benefit-templates.md).

# Benefit Templates

## GET /api/{tenantId}/admin/benefitTemplates

> List benefit templates

```json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"BenefitTemplates"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"security":[{"admin-bearer":["tenant.configuration.benefitTemplate:read"]},{"apiKey":[]}],"components":{"securitySchemes":{"admin-bearer":{"type":"oauth2","flows":{"implicit":{"authorizationUrl":"https://auth.neostore.cloud/authorize?audience=https://app.neostore.cloud/api/","scopes":{}}}},"apiKey":{"type":"apiKey","name":"X-API-KEY","in":"header"}},"schemas":{"BenefitTemplate":{"required":["id","type"],"type":"object","properties":{"id":{"minLength":1,"type":"string","description":"The benefit template's key, unique within the tenant and fixed once created."},"name":{"maxLength":200,"type":["null","string"],"description":"Name operators know the benefit template by in the admin console and in automations. Never shown\nto the holder, who sees Neo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplate.Content's title instead."},"enabled":{"type":"boolean","description":"Whether the benefit template can be granted. A disabled one is refused when granted to a single\npass, as an unknown benefit template, and skipped by automations and campaigns, without error."},"priority":{"type":["null","integer"],"description":"Rank of the issued benefit among the others on the same pass. Higher comes first; a benefit\nwith no priority comes after every benefit with one.","format":"int32"},"activationDate":{"oneOf":[{"type":"string","format":"date-time"},{"type":"integer","format":"int64"}],"description":"When benefits issued from this benefit template become redeemable. Omit for straight away. Accepts ISO 8601 date-time string or Unix epoch seconds in request inputs. Responses are serialized as ISO 8601 date-time strings."},"validityMode":{"description":"How each issued benefit's end of validity (its `deactivationDate`) is computed. Omit for\nbenefits that never expire.","$ref":"#/components/schemas/BenefitTemplateValidityMode"},"fixedDate":{"oneOf":[{"type":"string","format":"date-time"},{"type":"integer","format":"int64"}],"description":"The instant every issued benefit stops being redeemable. Required when Neo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplate.ValidityMode\nis `FixedDate`, unused otherwise. Accepts ISO 8601 date-time string or Unix epoch seconds in request inputs. Responses are serialized as ISO 8601 date-time strings."},"duration":{"type":["null","string"],"description":"How long each issued benefit stays redeemable, counted from the moment it is issued. Required when\nNeo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplate.ValidityMode is `Duration`, unused otherwise.","format":"date-span"},"type":{"description":"How the issued benefit is consumed: `OneTime` is redeemed once, `MultiUse` counts down\nNeo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplate.InitialValue uses, `Unlimited` is never used up.","$ref":"#/components/schemas/BenefitType"},"category":{"description":"What the benefit gives the holder, used to group and label it on the benefits page and in reports.","$ref":"#/components/schemas/BenefitCategory"},"tags":{"type":"array","items":{"type":"string"},"description":"Labels copied onto every issued benefit, for segmenting and reporting. Never shown to the holder."},"appearance":{"description":"Images copied onto every issued benefit. Omit for a benefit with no image.","$ref":"#/components/schemas/BenefitTemplateAppearance"},"content":{"description":"The title and description the holder reads, copied onto every issued benefit.","$ref":"#/components/schemas/BenefitTemplateContent"},"links":{"type":["null","object"],"properties":{"legalInformation":{"description":"A link shown as a button with the benefit on the benefits page.","$ref":"#/components/schemas/BenefitTemplateLink"},"callToAction":{"description":"A link shown as a button with the benefit on the benefits page.","$ref":"#/components/schemas/BenefitTemplateLink"},"termsAndConditions":{"description":"A link shown as a button with the benefit on the benefits page.","$ref":"#/components/schemas/BenefitTemplateLink"},"privacyPolicy":{"description":"A link shown as a button with the benefit on the benefits page.","$ref":"#/components/schemas/BenefitTemplateLink"},"howToUse":{"description":"A link shown as a button with the benefit on the benefits page.","$ref":"#/components/schemas/BenefitTemplateLink"},"website":{"description":"A link shown as a button with the benefit on the benefits page.","$ref":"#/components/schemas/BenefitTemplateLink"},"other":{"description":"A link shown as a button with the benefit on the benefits page.","$ref":"#/components/schemas/BenefitTemplateLink"}},"additionalProperties":false,"description":"Links shown with the benefit on the benefits page, keyed by purpose."},"initialValue":{"type":["null","number"],"description":"The number of uses a `MultiUse` benefit starts with - the \"5\" in \"3 of 5 left\".","format":"double"},"dataContent":{"type":["null","string"],"description":"Free text copied into each issued benefit's `data.content`, for a pass template or an integration\nto read. Never shown to the holder as such."},"passType":{"type":["null","string"],"description":"Pass template of a standalone wallet pass to create for each issued benefit, alongside the holder's\nown pass. Omit for a benefit that lives only on the holder's pass."},"code":{"description":"How each issued benefit gets the code staff scan or type to redeem it. Omit for a benefit with no\ncode.","$ref":"#/components/schemas/BenefitTemplateCodeSettings"},"removal":{"description":"When a benefit issued from this benefit template leaves the pass. Omit to remove it at end of validity.","$ref":"#/components/schemas/BenefitTemplateRemoval"},"behavior":{"description":"Where a benefit issued from this benefit template is surfaced, and what each surface does with it. Omit for the defaults.","$ref":"#/components/schemas/BenefitTemplateBehavior"},"creationDate":{"oneOf":[{"type":"string","format":"date-time"},{"type":"integer","format":"int64"}],"description":"When the benefit template was created. Set by the server; ignored on write. Null on benefit templates\ncreated before it was recorded. Accepts ISO 8601 date-time string or Unix epoch seconds in request inputs. Responses are serialized as ISO 8601 date-time strings."},"lastModificationDate":{"oneOf":[{"type":"string","format":"date-time"},{"type":"integer","format":"int64"}],"description":"When the benefit template definition last changed. Set by the server on every write; ignored on write. Accepts ISO 8601 date-time string or Unix epoch seconds in request inputs. Responses are serialized as ISO 8601 date-time strings."}},"additionalProperties":false,"description":"The reusable definition of a benefit: what a holder is given each time it is granted to a pass, by an\nautomation, a campaign or a single grant."},"BenefitTemplateValidityMode":{"enum":["fixedDate","duration"],"type":"string","description":"How the end of validity of a benefit issued from a benefit template is computed."},"BenefitType":{"enum":["oneTime","unlimited","multiUse"],"type":"string","description":"How a benefit is consumed, which decides what its movements mean and when it is used up."},"BenefitCategory":{"enum":["other","discount","freeProduct","service","access","giftCard"],"type":"string","description":"What a benefit gives the holder, used to group and label it on the benefits page and in reports."},"BenefitTemplateAppearance":{"type":"object","properties":{"images":{"type":"array","items":{"description":"A single image entry within a benefit template appearance.","$ref":"#/components/schemas/BenefitTemplateImage"},"description":"The images, at most one per slot; where a slot is named twice the last entry wins."}},"additionalProperties":false,"description":"The images a benefit template gives each benefit it issues."},"BenefitTemplateImage":{"required":["slot","url"],"type":"object","properties":{"slot":{"description":"Where the image is used: `main` for the headline visual, `thumbnail` for compact lists.","$ref":"#/components/schemas/BenefitImageSlot"},"url":{"description":"The image, per language. Each value is an `http`/`https` address, or the name of an image\nuploaded to this benefit template (e.g. `hero.png`).","$ref":"#/components/schemas/BenefitTemplateLocalizedString"}},"additionalProperties":false,"description":"A single image entry within a benefit template appearance."},"BenefitImageSlot":{"enum":["main","thumbnail"],"type":"string","description":"The image slots a benefit can fill."},"BenefitTemplateLocalizedString":{"required":["default"],"type":"object","properties":{"default":{"minLength":1,"type":"string","description":"The text shown to a holder whose language has no entry in Neo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateLocalizedString.Localizations."},"localizations":{"type":["null","object"],"additionalProperties":{"type":"string"},"description":"Per-language overrides, keyed by language code (e.g. `fr`, `en-US`)."}},"additionalProperties":false,"description":"A string with a mandatory default value and optional per-language overrides."},"BenefitTemplateContent":{"type":"object","properties":{"title":{"description":"The benefit's name as the holder sees it, on the benefits page and as a wallet pass field. Required\non create; a benefit without one is shown as \"Untitled benefit\".","$ref":"#/components/schemas/BenefitTemplateLocalizedString"},"description":{"description":"What the benefit gives and how to use it, shown on the benefits page and, when the behaviour asks for\nit, on the back of the wallet pass.","$ref":"#/components/schemas/BenefitTemplateLocalizedString"}},"additionalProperties":false,"description":"The holder-facing texts of a benefit template."},"BenefitTemplateLink":{"required":["link"],"type":"object","properties":{"title":{"description":"The button label. At most 100 characters per language.","$ref":"#/components/schemas/BenefitTemplateLocalizedString"},"link":{"type":"string","description":"The address the button opens: an absolute `https` URI.","format":"uri"}},"additionalProperties":false,"description":"A link shown as a button with the benefit on the benefits page."},"BenefitTemplateCodeSettings":{"type":"object","properties":{"format":{"description":"How the code is rendered to the holder: a barcode symbology, or `raw` for text only.","$ref":"#/components/schemas/BenefitCodeFormat"},"valueMode":{"description":"Where the code value comes from: `Shared` uses Neo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateCodeSettings.Value for every holder,\n`Autogenerated` draws a random one per benefit from Neo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateCodeSettings.Pattern, `Custom` runs\nNeo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateCodeSettings.Script. Omit for no code.","$ref":"#/components/schemas/BenefitTemplateCodeValueMode"},"value":{"type":["null","string"],"description":"The code every holder gets, e.g. a promotion code typed at checkout. Required when\nNeo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateCodeSettings.ValueMode is `Shared`."},"pattern":{"description":"Shape of the random code drawn for each benefit. Used when Neo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateCodeSettings.ValueMode is\n`Autogenerated`; omitted, a 10-character upper-case alphanumeric code is drawn.","$ref":"#/components/schemas/BenefitTemplateCodePattern"},"script":{"type":["null","string"],"description":"Body of the JavaScript function that returns the code, without its wrapper, e.g.\n`return \"X-\" + Date.now();`. Required when Neo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateCodeSettings.ValueMode is `Custom`."}},"additionalProperties":false,"description":"How each benefit issued from this benefit template gets its code, and how the code is rendered."},"BenefitCodeFormat":{"enum":["ean13","code128","qrCode","pdf417","aztec","dataMatrix","code39","raw"],"type":"string","description":"How a benefit's code is rendered to the holder, and so what the till or the Pass Scanner scans."},"BenefitTemplateCodeValueMode":{"enum":["shared","autogenerated","custom"],"type":"string","description":"Where the code of a benefit issued from a benefit template comes from."},"BenefitTemplateCodePattern":{"type":"object","properties":{"length":{"type":"integer","description":"Number of random characters, prefix and suffix excluded. Between the charset's minimum (Numeric 9,\nAlpha 7, Hex 8, Alphanumeric 6) and 64.","format":"int32"},"charset":{"description":"The characters the random part is drawn from. `ean13` requires `Numeric`.","$ref":"#/components/schemas/BenefitTemplateCodeCharset"},"prefix":{"type":["null","string"],"description":"Fixed text placed before the random part, e.g. a campaign marker. Digits only for `ean13`."},"suffix":{"type":["null","string"],"description":"Fixed text placed after the random part. Digits only for `ean13`."},"uppercase":{"type":"boolean","description":"Whether letters in the random part are upper-case (default) or lower-case. Prefix and suffix are kept as written."}},"additionalProperties":false,"description":"The shape of a randomly drawn code."},"BenefitTemplateCodeCharset":{"enum":["alphanumeric","numeric","alpha","hex"],"type":"string","description":"The characters the random part of an autogenerated code is drawn from."},"BenefitTemplateRemoval":{"type":"object","properties":{"mode":{"description":"Rule used to compute the benefit's deletion date.","$ref":"#/components/schemas/BenefitTemplateRemovalMode"},"days":{"maximum":3650,"minimum":1,"type":["null","integer"],"description":"How many days an expired benefit stays visible on the pass, shown as expired. Required when\nNeo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateRemoval.Mode is `AfterEndOfValidity`, dropped otherwise.","format":"int32"},"date":{"oneOf":[{"type":"string","format":"date-time"},{"type":"integer","format":"int64"}],"description":"The instant every issued benefit leaves the pass. Required when Neo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateRemoval.Mode is\n`FixedDate`, dropped otherwise. Accepts ISO 8601 date-time string or Unix epoch seconds in request inputs. Responses are serialized as ISO 8601 date-time strings."}},"additionalProperties":false,"description":"When the benefit issued from this benefit template is removed from the pass."},"BenefitTemplateRemovalMode":{"enum":["never","endOfValidity","afterEndOfValidity","fixedDate"],"type":"string","description":"How the deletion date of an issued benefit is derived."},"BenefitTemplateBehavior":{"type":"object","properties":{"mode":{"type":["null","array"],"items":{"description":"Where a benefit is shown and what each surface does with it.","$ref":"#/components/schemas/BenefitBehaviorMode"},"description":"The behaviours an issued benefit carries, one entry per behaviour."}},"additionalProperties":false,"description":"Where a benefit issued from the benefit template is surfaced, and what each surface does with it."},"BenefitBehaviorMode":{"enum":["none","showOnBenefitListPage","showOnPassScanner","redeemOnScan","useMainImageAsWalletImage","addDescriptionAsBackField"],"type":"string","description":"Where a benefit is shown and what each surface does with it."},"ProblemDetails":{"type":"object","properties":{"type":{"type":["null","string"]},"title":{"type":["null","string"]},"status":{"type":["null","integer"],"format":"int32"},"detail":{"type":["null","string"]},"instance":{"type":["null","string"]}},"additionalProperties":{}},"HttpValidationProblemDetails":{"type":"object","allOf":[{"$ref":"#/components/schemas/ProblemDetails"}],"properties":{"errors":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}},"additionalProperties":{}}}},"paths":{"/api/{tenantId}/admin/benefitTemplates":{"get":{"tags":["BenefitTemplates"],"summary":"List benefit templates","parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Benefit templates returned.","content":{"text/plain":{"schema":{"type":"array","items":{"description":"The reusable definition of a benefit: what a holder is given each time it is granted to a pass, by an\nautomation, a campaign or a single grant.","$ref":"#/components/schemas/BenefitTemplate"}}},"application/json":{"schema":{"type":"array","items":{"description":"The reusable definition of a benefit: what a holder is given each time it is granted to a pass, by an\nautomation, a campaign or a single grant.","$ref":"#/components/schemas/BenefitTemplate"}}},"text/json":{"schema":{"type":"array","items":{"description":"The reusable definition of a benefit: what a holder is given each time it is granted to a pass, by an\nautomation, a campaign or a single grant.","$ref":"#/components/schemas/BenefitTemplate"}}}}},"401":{"description":"The caller is not authenticated.","content":{"application/problem+json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"403":{"description":"The caller lacks the <c>tenant.configuration.benefitTemplate:read</c> scope.","content":{"application/problem+json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"429":{"description":"Over 1200 requests per minute to this endpoint for the tenant (default limit); retry after <c>Retry-After</c>.","headers":{"Retry-After":{"description":"Seconds to wait before retrying. Sent when the limiter knows it.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}}}}}}
```

## Create benefit template

> The id must be unique within the tenant.

```json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"BenefitTemplates"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"security":[{"admin-bearer":["tenant.configuration.benefitTemplate:write"]},{"apiKey":[]}],"components":{"securitySchemes":{"admin-bearer":{"type":"oauth2","flows":{"implicit":{"authorizationUrl":"https://auth.neostore.cloud/authorize?audience=https://app.neostore.cloud/api/","scopes":{}}}},"apiKey":{"type":"apiKey","name":"X-API-KEY","in":"header"}},"schemas":{"BenefitTemplate":{"required":["id","type"],"type":"object","properties":{"id":{"minLength":1,"type":"string","description":"The benefit template's key, unique within the tenant and fixed once created."},"name":{"maxLength":200,"type":["null","string"],"description":"Name operators know the benefit template by in the admin console and in automations. Never shown\nto the holder, who sees Neo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplate.Content's title instead."},"enabled":{"type":"boolean","description":"Whether the benefit template can be granted. A disabled one is refused when granted to a single\npass, as an unknown benefit template, and skipped by automations and campaigns, without error."},"priority":{"type":["null","integer"],"description":"Rank of the issued benefit among the others on the same pass. Higher comes first; a benefit\nwith no priority comes after every benefit with one.","format":"int32"},"activationDate":{"oneOf":[{"type":"string","format":"date-time"},{"type":"integer","format":"int64"}],"description":"When benefits issued from this benefit template become redeemable. Omit for straight away. Accepts ISO 8601 date-time string or Unix epoch seconds in request inputs. Responses are serialized as ISO 8601 date-time strings."},"validityMode":{"description":"How each issued benefit's end of validity (its `deactivationDate`) is computed. Omit for\nbenefits that never expire.","$ref":"#/components/schemas/BenefitTemplateValidityMode"},"fixedDate":{"oneOf":[{"type":"string","format":"date-time"},{"type":"integer","format":"int64"}],"description":"The instant every issued benefit stops being redeemable. Required when Neo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplate.ValidityMode\nis `FixedDate`, unused otherwise. Accepts ISO 8601 date-time string or Unix epoch seconds in request inputs. Responses are serialized as ISO 8601 date-time strings."},"duration":{"type":["null","string"],"description":"How long each issued benefit stays redeemable, counted from the moment it is issued. Required when\nNeo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplate.ValidityMode is `Duration`, unused otherwise.","format":"date-span"},"type":{"description":"How the issued benefit is consumed: `OneTime` is redeemed once, `MultiUse` counts down\nNeo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplate.InitialValue uses, `Unlimited` is never used up.","$ref":"#/components/schemas/BenefitType"},"category":{"description":"What the benefit gives the holder, used to group and label it on the benefits page and in reports.","$ref":"#/components/schemas/BenefitCategory"},"tags":{"type":"array","items":{"type":"string"},"description":"Labels copied onto every issued benefit, for segmenting and reporting. Never shown to the holder."},"appearance":{"description":"Images copied onto every issued benefit. Omit for a benefit with no image.","$ref":"#/components/schemas/BenefitTemplateAppearance"},"content":{"description":"The title and description the holder reads, copied onto every issued benefit.","$ref":"#/components/schemas/BenefitTemplateContent"},"links":{"type":["null","object"],"properties":{"legalInformation":{"description":"A link shown as a button with the benefit on the benefits page.","$ref":"#/components/schemas/BenefitTemplateLink"},"callToAction":{"description":"A link shown as a button with the benefit on the benefits page.","$ref":"#/components/schemas/BenefitTemplateLink"},"termsAndConditions":{"description":"A link shown as a button with the benefit on the benefits page.","$ref":"#/components/schemas/BenefitTemplateLink"},"privacyPolicy":{"description":"A link shown as a button with the benefit on the benefits page.","$ref":"#/components/schemas/BenefitTemplateLink"},"howToUse":{"description":"A link shown as a button with the benefit on the benefits page.","$ref":"#/components/schemas/BenefitTemplateLink"},"website":{"description":"A link shown as a button with the benefit on the benefits page.","$ref":"#/components/schemas/BenefitTemplateLink"},"other":{"description":"A link shown as a button with the benefit on the benefits page.","$ref":"#/components/schemas/BenefitTemplateLink"}},"additionalProperties":false,"description":"Links shown with the benefit on the benefits page, keyed by purpose."},"initialValue":{"type":["null","number"],"description":"The number of uses a `MultiUse` benefit starts with - the \"5\" in \"3 of 5 left\".","format":"double"},"dataContent":{"type":["null","string"],"description":"Free text copied into each issued benefit's `data.content`, for a pass template or an integration\nto read. Never shown to the holder as such."},"passType":{"type":["null","string"],"description":"Pass template of a standalone wallet pass to create for each issued benefit, alongside the holder's\nown pass. Omit for a benefit that lives only on the holder's pass."},"code":{"description":"How each issued benefit gets the code staff scan or type to redeem it. Omit for a benefit with no\ncode.","$ref":"#/components/schemas/BenefitTemplateCodeSettings"},"removal":{"description":"When a benefit issued from this benefit template leaves the pass. Omit to remove it at end of validity.","$ref":"#/components/schemas/BenefitTemplateRemoval"},"behavior":{"description":"Where a benefit issued from this benefit template is surfaced, and what each surface does with it. Omit for the defaults.","$ref":"#/components/schemas/BenefitTemplateBehavior"},"creationDate":{"oneOf":[{"type":"string","format":"date-time"},{"type":"integer","format":"int64"}],"description":"When the benefit template was created. Set by the server; ignored on write. Null on benefit templates\ncreated before it was recorded. Accepts ISO 8601 date-time string or Unix epoch seconds in request inputs. Responses are serialized as ISO 8601 date-time strings."},"lastModificationDate":{"oneOf":[{"type":"string","format":"date-time"},{"type":"integer","format":"int64"}],"description":"When the benefit template definition last changed. Set by the server on every write; ignored on write. Accepts ISO 8601 date-time string or Unix epoch seconds in request inputs. Responses are serialized as ISO 8601 date-time strings."}},"additionalProperties":false,"description":"The reusable definition of a benefit: what a holder is given each time it is granted to a pass, by an\nautomation, a campaign or a single grant."},"BenefitTemplateValidityMode":{"enum":["fixedDate","duration"],"type":"string","description":"How the end of validity of a benefit issued from a benefit template is computed."},"BenefitType":{"enum":["oneTime","unlimited","multiUse"],"type":"string","description":"How a benefit is consumed, which decides what its movements mean and when it is used up."},"BenefitCategory":{"enum":["other","discount","freeProduct","service","access","giftCard"],"type":"string","description":"What a benefit gives the holder, used to group and label it on the benefits page and in reports."},"BenefitTemplateAppearance":{"type":"object","properties":{"images":{"type":"array","items":{"description":"A single image entry within a benefit template appearance.","$ref":"#/components/schemas/BenefitTemplateImage"},"description":"The images, at most one per slot; where a slot is named twice the last entry wins."}},"additionalProperties":false,"description":"The images a benefit template gives each benefit it issues."},"BenefitTemplateImage":{"required":["slot","url"],"type":"object","properties":{"slot":{"description":"Where the image is used: `main` for the headline visual, `thumbnail` for compact lists.","$ref":"#/components/schemas/BenefitImageSlot"},"url":{"description":"The image, per language. Each value is an `http`/`https` address, or the name of an image\nuploaded to this benefit template (e.g. `hero.png`).","$ref":"#/components/schemas/BenefitTemplateLocalizedString"}},"additionalProperties":false,"description":"A single image entry within a benefit template appearance."},"BenefitImageSlot":{"enum":["main","thumbnail"],"type":"string","description":"The image slots a benefit can fill."},"BenefitTemplateLocalizedString":{"required":["default"],"type":"object","properties":{"default":{"minLength":1,"type":"string","description":"The text shown to a holder whose language has no entry in Neo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateLocalizedString.Localizations."},"localizations":{"type":["null","object"],"additionalProperties":{"type":"string"},"description":"Per-language overrides, keyed by language code (e.g. `fr`, `en-US`)."}},"additionalProperties":false,"description":"A string with a mandatory default value and optional per-language overrides."},"BenefitTemplateContent":{"type":"object","properties":{"title":{"description":"The benefit's name as the holder sees it, on the benefits page and as a wallet pass field. Required\non create; a benefit without one is shown as \"Untitled benefit\".","$ref":"#/components/schemas/BenefitTemplateLocalizedString"},"description":{"description":"What the benefit gives and how to use it, shown on the benefits page and, when the behaviour asks for\nit, on the back of the wallet pass.","$ref":"#/components/schemas/BenefitTemplateLocalizedString"}},"additionalProperties":false,"description":"The holder-facing texts of a benefit template."},"BenefitTemplateLink":{"required":["link"],"type":"object","properties":{"title":{"description":"The button label. At most 100 characters per language.","$ref":"#/components/schemas/BenefitTemplateLocalizedString"},"link":{"type":"string","description":"The address the button opens: an absolute `https` URI.","format":"uri"}},"additionalProperties":false,"description":"A link shown as a button with the benefit on the benefits page."},"BenefitTemplateCodeSettings":{"type":"object","properties":{"format":{"description":"How the code is rendered to the holder: a barcode symbology, or `raw` for text only.","$ref":"#/components/schemas/BenefitCodeFormat"},"valueMode":{"description":"Where the code value comes from: `Shared` uses Neo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateCodeSettings.Value for every holder,\n`Autogenerated` draws a random one per benefit from Neo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateCodeSettings.Pattern, `Custom` runs\nNeo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateCodeSettings.Script. Omit for no code.","$ref":"#/components/schemas/BenefitTemplateCodeValueMode"},"value":{"type":["null","string"],"description":"The code every holder gets, e.g. a promotion code typed at checkout. Required when\nNeo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateCodeSettings.ValueMode is `Shared`."},"pattern":{"description":"Shape of the random code drawn for each benefit. Used when Neo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateCodeSettings.ValueMode is\n`Autogenerated`; omitted, a 10-character upper-case alphanumeric code is drawn.","$ref":"#/components/schemas/BenefitTemplateCodePattern"},"script":{"type":["null","string"],"description":"Body of the JavaScript function that returns the code, without its wrapper, e.g.\n`return \"X-\" + Date.now();`. Required when Neo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateCodeSettings.ValueMode is `Custom`."}},"additionalProperties":false,"description":"How each benefit issued from this benefit template gets its code, and how the code is rendered."},"BenefitCodeFormat":{"enum":["ean13","code128","qrCode","pdf417","aztec","dataMatrix","code39","raw"],"type":"string","description":"How a benefit's code is rendered to the holder, and so what the till or the Pass Scanner scans."},"BenefitTemplateCodeValueMode":{"enum":["shared","autogenerated","custom"],"type":"string","description":"Where the code of a benefit issued from a benefit template comes from."},"BenefitTemplateCodePattern":{"type":"object","properties":{"length":{"type":"integer","description":"Number of random characters, prefix and suffix excluded. Between the charset's minimum (Numeric 9,\nAlpha 7, Hex 8, Alphanumeric 6) and 64.","format":"int32"},"charset":{"description":"The characters the random part is drawn from. `ean13` requires `Numeric`.","$ref":"#/components/schemas/BenefitTemplateCodeCharset"},"prefix":{"type":["null","string"],"description":"Fixed text placed before the random part, e.g. a campaign marker. Digits only for `ean13`."},"suffix":{"type":["null","string"],"description":"Fixed text placed after the random part. Digits only for `ean13`."},"uppercase":{"type":"boolean","description":"Whether letters in the random part are upper-case (default) or lower-case. Prefix and suffix are kept as written."}},"additionalProperties":false,"description":"The shape of a randomly drawn code."},"BenefitTemplateCodeCharset":{"enum":["alphanumeric","numeric","alpha","hex"],"type":"string","description":"The characters the random part of an autogenerated code is drawn from."},"BenefitTemplateRemoval":{"type":"object","properties":{"mode":{"description":"Rule used to compute the benefit's deletion date.","$ref":"#/components/schemas/BenefitTemplateRemovalMode"},"days":{"maximum":3650,"minimum":1,"type":["null","integer"],"description":"How many days an expired benefit stays visible on the pass, shown as expired. Required when\nNeo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateRemoval.Mode is `AfterEndOfValidity`, dropped otherwise.","format":"int32"},"date":{"oneOf":[{"type":"string","format":"date-time"},{"type":"integer","format":"int64"}],"description":"The instant every issued benefit leaves the pass. Required when Neo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateRemoval.Mode is\n`FixedDate`, dropped otherwise. Accepts ISO 8601 date-time string or Unix epoch seconds in request inputs. Responses are serialized as ISO 8601 date-time strings."}},"additionalProperties":false,"description":"When the benefit issued from this benefit template is removed from the pass."},"BenefitTemplateRemovalMode":{"enum":["never","endOfValidity","afterEndOfValidity","fixedDate"],"type":"string","description":"How the deletion date of an issued benefit is derived."},"BenefitTemplateBehavior":{"type":"object","properties":{"mode":{"type":["null","array"],"items":{"description":"Where a benefit is shown and what each surface does with it.","$ref":"#/components/schemas/BenefitBehaviorMode"},"description":"The behaviours an issued benefit carries, one entry per behaviour."}},"additionalProperties":false,"description":"Where a benefit issued from the benefit template is surfaced, and what each surface does with it."},"BenefitBehaviorMode":{"enum":["none","showOnBenefitListPage","showOnPassScanner","redeemOnScan","useMainImageAsWalletImage","addDescriptionAsBackField"],"type":"string","description":"Where a benefit is shown and what each surface does with it."},"ProblemDetails":{"type":"object","properties":{"type":{"type":["null","string"]},"title":{"type":["null","string"]},"status":{"type":["null","integer"],"format":"int32"},"detail":{"type":["null","string"]},"instance":{"type":["null","string"]}},"additionalProperties":{}},"HttpValidationProblemDetails":{"type":"object","allOf":[{"$ref":"#/components/schemas/ProblemDetails"}],"properties":{"errors":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}},"additionalProperties":{}}}},"paths":{"/api/{tenantId}/admin/benefitTemplates":{"post":{"tags":["BenefitTemplates"],"summary":"Create benefit template","description":"The id must be unique within the tenant.","parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Benefit template to create.","content":{"application/json":{"schema":{"description":"The reusable definition of a benefit: what a holder is given each time it is granted to a pass, by an\nautomation, a campaign or a single grant.","$ref":"#/components/schemas/BenefitTemplate"}},"text/json":{"schema":{"description":"The reusable definition of a benefit: what a holder is given each time it is granted to a pass, by an\nautomation, a campaign or a single grant.","$ref":"#/components/schemas/BenefitTemplate"}},"application/*+json":{"schema":{"description":"The reusable definition of a benefit: what a holder is given each time it is granted to a pass, by an\nautomation, a campaign or a single grant.","$ref":"#/components/schemas/BenefitTemplate"}}},"required":true},"responses":{"201":{"description":"Benefit template created.","content":{"text/plain":{"schema":{"description":"The reusable definition of a benefit: what a holder is given each time it is granted to a pass, by an\nautomation, a campaign or a single grant.","$ref":"#/components/schemas/BenefitTemplate"}},"application/json":{"schema":{"description":"The reusable definition of a benefit: what a holder is given each time it is granted to a pass, by an\nautomation, a campaign or a single grant.","$ref":"#/components/schemas/BenefitTemplate"}},"text/json":{"schema":{"description":"The reusable definition of a benefit: what a holder is given each time it is granted to a pass, by an\nautomation, a campaign or a single grant.","$ref":"#/components/schemas/BenefitTemplate"}}}},"400":{"description":"Invalid payload.","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"401":{"description":"The caller is not authenticated.","content":{"application/problem+json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"403":{"description":"The caller lacks the <c>tenant.configuration.benefitTemplate:write</c> scope.","content":{"application/problem+json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"409":{"description":"Id already exists, or another template write is in progress.","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"429":{"description":"Over 1200 requests per minute to this endpoint for the tenant (default limit); retry after <c>Retry-After</c>.","headers":{"Retry-After":{"description":"Seconds to wait before retrying. Sent when the limiter knows it.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}}}}}}
```

## GET /api/{tenantId}/admin/benefitTemplates/{id}

> Get benefit template

```json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"BenefitTemplates"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"security":[{"admin-bearer":["tenant.configuration.benefitTemplate:read"]},{"apiKey":[]}],"components":{"securitySchemes":{"admin-bearer":{"type":"oauth2","flows":{"implicit":{"authorizationUrl":"https://auth.neostore.cloud/authorize?audience=https://app.neostore.cloud/api/","scopes":{}}}},"apiKey":{"type":"apiKey","name":"X-API-KEY","in":"header"}},"schemas":{"BenefitTemplate":{"required":["id","type"],"type":"object","properties":{"id":{"minLength":1,"type":"string","description":"The benefit template's key, unique within the tenant and fixed once created."},"name":{"maxLength":200,"type":["null","string"],"description":"Name operators know the benefit template by in the admin console and in automations. Never shown\nto the holder, who sees Neo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplate.Content's title instead."},"enabled":{"type":"boolean","description":"Whether the benefit template can be granted. A disabled one is refused when granted to a single\npass, as an unknown benefit template, and skipped by automations and campaigns, without error."},"priority":{"type":["null","integer"],"description":"Rank of the issued benefit among the others on the same pass. Higher comes first; a benefit\nwith no priority comes after every benefit with one.","format":"int32"},"activationDate":{"oneOf":[{"type":"string","format":"date-time"},{"type":"integer","format":"int64"}],"description":"When benefits issued from this benefit template become redeemable. Omit for straight away. Accepts ISO 8601 date-time string or Unix epoch seconds in request inputs. Responses are serialized as ISO 8601 date-time strings."},"validityMode":{"description":"How each issued benefit's end of validity (its `deactivationDate`) is computed. Omit for\nbenefits that never expire.","$ref":"#/components/schemas/BenefitTemplateValidityMode"},"fixedDate":{"oneOf":[{"type":"string","format":"date-time"},{"type":"integer","format":"int64"}],"description":"The instant every issued benefit stops being redeemable. Required when Neo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplate.ValidityMode\nis `FixedDate`, unused otherwise. Accepts ISO 8601 date-time string or Unix epoch seconds in request inputs. Responses are serialized as ISO 8601 date-time strings."},"duration":{"type":["null","string"],"description":"How long each issued benefit stays redeemable, counted from the moment it is issued. Required when\nNeo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplate.ValidityMode is `Duration`, unused otherwise.","format":"date-span"},"type":{"description":"How the issued benefit is consumed: `OneTime` is redeemed once, `MultiUse` counts down\nNeo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplate.InitialValue uses, `Unlimited` is never used up.","$ref":"#/components/schemas/BenefitType"},"category":{"description":"What the benefit gives the holder, used to group and label it on the benefits page and in reports.","$ref":"#/components/schemas/BenefitCategory"},"tags":{"type":"array","items":{"type":"string"},"description":"Labels copied onto every issued benefit, for segmenting and reporting. Never shown to the holder."},"appearance":{"description":"Images copied onto every issued benefit. Omit for a benefit with no image.","$ref":"#/components/schemas/BenefitTemplateAppearance"},"content":{"description":"The title and description the holder reads, copied onto every issued benefit.","$ref":"#/components/schemas/BenefitTemplateContent"},"links":{"type":["null","object"],"properties":{"legalInformation":{"description":"A link shown as a button with the benefit on the benefits page.","$ref":"#/components/schemas/BenefitTemplateLink"},"callToAction":{"description":"A link shown as a button with the benefit on the benefits page.","$ref":"#/components/schemas/BenefitTemplateLink"},"termsAndConditions":{"description":"A link shown as a button with the benefit on the benefits page.","$ref":"#/components/schemas/BenefitTemplateLink"},"privacyPolicy":{"description":"A link shown as a button with the benefit on the benefits page.","$ref":"#/components/schemas/BenefitTemplateLink"},"howToUse":{"description":"A link shown as a button with the benefit on the benefits page.","$ref":"#/components/schemas/BenefitTemplateLink"},"website":{"description":"A link shown as a button with the benefit on the benefits page.","$ref":"#/components/schemas/BenefitTemplateLink"},"other":{"description":"A link shown as a button with the benefit on the benefits page.","$ref":"#/components/schemas/BenefitTemplateLink"}},"additionalProperties":false,"description":"Links shown with the benefit on the benefits page, keyed by purpose."},"initialValue":{"type":["null","number"],"description":"The number of uses a `MultiUse` benefit starts with - the \"5\" in \"3 of 5 left\".","format":"double"},"dataContent":{"type":["null","string"],"description":"Free text copied into each issued benefit's `data.content`, for a pass template or an integration\nto read. Never shown to the holder as such."},"passType":{"type":["null","string"],"description":"Pass template of a standalone wallet pass to create for each issued benefit, alongside the holder's\nown pass. Omit for a benefit that lives only on the holder's pass."},"code":{"description":"How each issued benefit gets the code staff scan or type to redeem it. Omit for a benefit with no\ncode.","$ref":"#/components/schemas/BenefitTemplateCodeSettings"},"removal":{"description":"When a benefit issued from this benefit template leaves the pass. Omit to remove it at end of validity.","$ref":"#/components/schemas/BenefitTemplateRemoval"},"behavior":{"description":"Where a benefit issued from this benefit template is surfaced, and what each surface does with it. Omit for the defaults.","$ref":"#/components/schemas/BenefitTemplateBehavior"},"creationDate":{"oneOf":[{"type":"string","format":"date-time"},{"type":"integer","format":"int64"}],"description":"When the benefit template was created. Set by the server; ignored on write. Null on benefit templates\ncreated before it was recorded. Accepts ISO 8601 date-time string or Unix epoch seconds in request inputs. Responses are serialized as ISO 8601 date-time strings."},"lastModificationDate":{"oneOf":[{"type":"string","format":"date-time"},{"type":"integer","format":"int64"}],"description":"When the benefit template definition last changed. Set by the server on every write; ignored on write. Accepts ISO 8601 date-time string or Unix epoch seconds in request inputs. Responses are serialized as ISO 8601 date-time strings."}},"additionalProperties":false,"description":"The reusable definition of a benefit: what a holder is given each time it is granted to a pass, by an\nautomation, a campaign or a single grant."},"BenefitTemplateValidityMode":{"enum":["fixedDate","duration"],"type":"string","description":"How the end of validity of a benefit issued from a benefit template is computed."},"BenefitType":{"enum":["oneTime","unlimited","multiUse"],"type":"string","description":"How a benefit is consumed, which decides what its movements mean and when it is used up."},"BenefitCategory":{"enum":["other","discount","freeProduct","service","access","giftCard"],"type":"string","description":"What a benefit gives the holder, used to group and label it on the benefits page and in reports."},"BenefitTemplateAppearance":{"type":"object","properties":{"images":{"type":"array","items":{"description":"A single image entry within a benefit template appearance.","$ref":"#/components/schemas/BenefitTemplateImage"},"description":"The images, at most one per slot; where a slot is named twice the last entry wins."}},"additionalProperties":false,"description":"The images a benefit template gives each benefit it issues."},"BenefitTemplateImage":{"required":["slot","url"],"type":"object","properties":{"slot":{"description":"Where the image is used: `main` for the headline visual, `thumbnail` for compact lists.","$ref":"#/components/schemas/BenefitImageSlot"},"url":{"description":"The image, per language. Each value is an `http`/`https` address, or the name of an image\nuploaded to this benefit template (e.g. `hero.png`).","$ref":"#/components/schemas/BenefitTemplateLocalizedString"}},"additionalProperties":false,"description":"A single image entry within a benefit template appearance."},"BenefitImageSlot":{"enum":["main","thumbnail"],"type":"string","description":"The image slots a benefit can fill."},"BenefitTemplateLocalizedString":{"required":["default"],"type":"object","properties":{"default":{"minLength":1,"type":"string","description":"The text shown to a holder whose language has no entry in Neo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateLocalizedString.Localizations."},"localizations":{"type":["null","object"],"additionalProperties":{"type":"string"},"description":"Per-language overrides, keyed by language code (e.g. `fr`, `en-US`)."}},"additionalProperties":false,"description":"A string with a mandatory default value and optional per-language overrides."},"BenefitTemplateContent":{"type":"object","properties":{"title":{"description":"The benefit's name as the holder sees it, on the benefits page and as a wallet pass field. Required\non create; a benefit without one is shown as \"Untitled benefit\".","$ref":"#/components/schemas/BenefitTemplateLocalizedString"},"description":{"description":"What the benefit gives and how to use it, shown on the benefits page and, when the behaviour asks for\nit, on the back of the wallet pass.","$ref":"#/components/schemas/BenefitTemplateLocalizedString"}},"additionalProperties":false,"description":"The holder-facing texts of a benefit template."},"BenefitTemplateLink":{"required":["link"],"type":"object","properties":{"title":{"description":"The button label. At most 100 characters per language.","$ref":"#/components/schemas/BenefitTemplateLocalizedString"},"link":{"type":"string","description":"The address the button opens: an absolute `https` URI.","format":"uri"}},"additionalProperties":false,"description":"A link shown as a button with the benefit on the benefits page."},"BenefitTemplateCodeSettings":{"type":"object","properties":{"format":{"description":"How the code is rendered to the holder: a barcode symbology, or `raw` for text only.","$ref":"#/components/schemas/BenefitCodeFormat"},"valueMode":{"description":"Where the code value comes from: `Shared` uses Neo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateCodeSettings.Value for every holder,\n`Autogenerated` draws a random one per benefit from Neo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateCodeSettings.Pattern, `Custom` runs\nNeo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateCodeSettings.Script. Omit for no code.","$ref":"#/components/schemas/BenefitTemplateCodeValueMode"},"value":{"type":["null","string"],"description":"The code every holder gets, e.g. a promotion code typed at checkout. Required when\nNeo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateCodeSettings.ValueMode is `Shared`."},"pattern":{"description":"Shape of the random code drawn for each benefit. Used when Neo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateCodeSettings.ValueMode is\n`Autogenerated`; omitted, a 10-character upper-case alphanumeric code is drawn.","$ref":"#/components/schemas/BenefitTemplateCodePattern"},"script":{"type":["null","string"],"description":"Body of the JavaScript function that returns the code, without its wrapper, e.g.\n`return \"X-\" + Date.now();`. Required when Neo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateCodeSettings.ValueMode is `Custom`."}},"additionalProperties":false,"description":"How each benefit issued from this benefit template gets its code, and how the code is rendered."},"BenefitCodeFormat":{"enum":["ean13","code128","qrCode","pdf417","aztec","dataMatrix","code39","raw"],"type":"string","description":"How a benefit's code is rendered to the holder, and so what the till or the Pass Scanner scans."},"BenefitTemplateCodeValueMode":{"enum":["shared","autogenerated","custom"],"type":"string","description":"Where the code of a benefit issued from a benefit template comes from."},"BenefitTemplateCodePattern":{"type":"object","properties":{"length":{"type":"integer","description":"Number of random characters, prefix and suffix excluded. Between the charset's minimum (Numeric 9,\nAlpha 7, Hex 8, Alphanumeric 6) and 64.","format":"int32"},"charset":{"description":"The characters the random part is drawn from. `ean13` requires `Numeric`.","$ref":"#/components/schemas/BenefitTemplateCodeCharset"},"prefix":{"type":["null","string"],"description":"Fixed text placed before the random part, e.g. a campaign marker. Digits only for `ean13`."},"suffix":{"type":["null","string"],"description":"Fixed text placed after the random part. Digits only for `ean13`."},"uppercase":{"type":"boolean","description":"Whether letters in the random part are upper-case (default) or lower-case. Prefix and suffix are kept as written."}},"additionalProperties":false,"description":"The shape of a randomly drawn code."},"BenefitTemplateCodeCharset":{"enum":["alphanumeric","numeric","alpha","hex"],"type":"string","description":"The characters the random part of an autogenerated code is drawn from."},"BenefitTemplateRemoval":{"type":"object","properties":{"mode":{"description":"Rule used to compute the benefit's deletion date.","$ref":"#/components/schemas/BenefitTemplateRemovalMode"},"days":{"maximum":3650,"minimum":1,"type":["null","integer"],"description":"How many days an expired benefit stays visible on the pass, shown as expired. Required when\nNeo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateRemoval.Mode is `AfterEndOfValidity`, dropped otherwise.","format":"int32"},"date":{"oneOf":[{"type":"string","format":"date-time"},{"type":"integer","format":"int64"}],"description":"The instant every issued benefit leaves the pass. Required when Neo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateRemoval.Mode is\n`FixedDate`, dropped otherwise. Accepts ISO 8601 date-time string or Unix epoch seconds in request inputs. Responses are serialized as ISO 8601 date-time strings."}},"additionalProperties":false,"description":"When the benefit issued from this benefit template is removed from the pass."},"BenefitTemplateRemovalMode":{"enum":["never","endOfValidity","afterEndOfValidity","fixedDate"],"type":"string","description":"How the deletion date of an issued benefit is derived."},"BenefitTemplateBehavior":{"type":"object","properties":{"mode":{"type":["null","array"],"items":{"description":"Where a benefit is shown and what each surface does with it.","$ref":"#/components/schemas/BenefitBehaviorMode"},"description":"The behaviours an issued benefit carries, one entry per behaviour."}},"additionalProperties":false,"description":"Where a benefit issued from the benefit template is surfaced, and what each surface does with it."},"BenefitBehaviorMode":{"enum":["none","showOnBenefitListPage","showOnPassScanner","redeemOnScan","useMainImageAsWalletImage","addDescriptionAsBackField"],"type":"string","description":"Where a benefit is shown and what each surface does with it."},"ProblemDetails":{"type":"object","properties":{"type":{"type":["null","string"]},"title":{"type":["null","string"]},"status":{"type":["null","integer"],"format":"int32"},"detail":{"type":["null","string"]},"instance":{"type":["null","string"]}},"additionalProperties":{}},"HttpValidationProblemDetails":{"type":"object","allOf":[{"$ref":"#/components/schemas/ProblemDetails"}],"properties":{"errors":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}},"additionalProperties":{}}}},"paths":{"/api/{tenantId}/admin/benefitTemplates/{id}":{"get":{"tags":["BenefitTemplates"],"summary":"Get benefit template","parameters":[{"name":"id","in":"path","description":"Benefit template id.","required":true,"schema":{"type":"string"}},{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Benefit template returned.","content":{"text/plain":{"schema":{"description":"The reusable definition of a benefit: what a holder is given each time it is granted to a pass, by an\nautomation, a campaign or a single grant.","$ref":"#/components/schemas/BenefitTemplate"}},"application/json":{"schema":{"description":"The reusable definition of a benefit: what a holder is given each time it is granted to a pass, by an\nautomation, a campaign or a single grant.","$ref":"#/components/schemas/BenefitTemplate"}},"text/json":{"schema":{"description":"The reusable definition of a benefit: what a holder is given each time it is granted to a pass, by an\nautomation, a campaign or a single grant.","$ref":"#/components/schemas/BenefitTemplate"}}}},"401":{"description":"The caller is not authenticated.","content":{"application/problem+json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"403":{"description":"The caller lacks the <c>tenant.configuration.benefitTemplate:read</c> scope.","content":{"application/problem+json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"404":{"description":"Benefit template not found.","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"429":{"description":"Over 1200 requests per minute to this endpoint for the tenant (default limit); retry after <c>Retry-After</c>.","headers":{"Retry-After":{"description":"Seconds to wait before retrying. Sent when the limiter knows it.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}}}}}}
```

## Update benefit template

> Benefits already issued keep what they were given unless updateBenefits is set: then every live, redeemable benefit is rewritten from the new definition after the response,\
> replacing any edit made on that benefit (movements, creation date and code are kept), and the passes showing them are updated.

```json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"BenefitTemplates"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"security":[{"admin-bearer":["tenant.configuration.benefitTemplate:write"]},{"apiKey":[]}],"components":{"securitySchemes":{"admin-bearer":{"type":"oauth2","flows":{"implicit":{"authorizationUrl":"https://auth.neostore.cloud/authorize?audience=https://app.neostore.cloud/api/","scopes":{}}}},"apiKey":{"type":"apiKey","name":"X-API-KEY","in":"header"}},"schemas":{"BenefitTemplate":{"required":["id","type"],"type":"object","properties":{"id":{"minLength":1,"type":"string","description":"The benefit template's key, unique within the tenant and fixed once created."},"name":{"maxLength":200,"type":["null","string"],"description":"Name operators know the benefit template by in the admin console and in automations. Never shown\nto the holder, who sees Neo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplate.Content's title instead."},"enabled":{"type":"boolean","description":"Whether the benefit template can be granted. A disabled one is refused when granted to a single\npass, as an unknown benefit template, and skipped by automations and campaigns, without error."},"priority":{"type":["null","integer"],"description":"Rank of the issued benefit among the others on the same pass. Higher comes first; a benefit\nwith no priority comes after every benefit with one.","format":"int32"},"activationDate":{"oneOf":[{"type":"string","format":"date-time"},{"type":"integer","format":"int64"}],"description":"When benefits issued from this benefit template become redeemable. Omit for straight away. Accepts ISO 8601 date-time string or Unix epoch seconds in request inputs. Responses are serialized as ISO 8601 date-time strings."},"validityMode":{"description":"How each issued benefit's end of validity (its `deactivationDate`) is computed. Omit for\nbenefits that never expire.","$ref":"#/components/schemas/BenefitTemplateValidityMode"},"fixedDate":{"oneOf":[{"type":"string","format":"date-time"},{"type":"integer","format":"int64"}],"description":"The instant every issued benefit stops being redeemable. Required when Neo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplate.ValidityMode\nis `FixedDate`, unused otherwise. Accepts ISO 8601 date-time string or Unix epoch seconds in request inputs. Responses are serialized as ISO 8601 date-time strings."},"duration":{"type":["null","string"],"description":"How long each issued benefit stays redeemable, counted from the moment it is issued. Required when\nNeo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplate.ValidityMode is `Duration`, unused otherwise.","format":"date-span"},"type":{"description":"How the issued benefit is consumed: `OneTime` is redeemed once, `MultiUse` counts down\nNeo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplate.InitialValue uses, `Unlimited` is never used up.","$ref":"#/components/schemas/BenefitType"},"category":{"description":"What the benefit gives the holder, used to group and label it on the benefits page and in reports.","$ref":"#/components/schemas/BenefitCategory"},"tags":{"type":"array","items":{"type":"string"},"description":"Labels copied onto every issued benefit, for segmenting and reporting. Never shown to the holder."},"appearance":{"description":"Images copied onto every issued benefit. Omit for a benefit with no image.","$ref":"#/components/schemas/BenefitTemplateAppearance"},"content":{"description":"The title and description the holder reads, copied onto every issued benefit.","$ref":"#/components/schemas/BenefitTemplateContent"},"links":{"type":["null","object"],"properties":{"legalInformation":{"description":"A link shown as a button with the benefit on the benefits page.","$ref":"#/components/schemas/BenefitTemplateLink"},"callToAction":{"description":"A link shown as a button with the benefit on the benefits page.","$ref":"#/components/schemas/BenefitTemplateLink"},"termsAndConditions":{"description":"A link shown as a button with the benefit on the benefits page.","$ref":"#/components/schemas/BenefitTemplateLink"},"privacyPolicy":{"description":"A link shown as a button with the benefit on the benefits page.","$ref":"#/components/schemas/BenefitTemplateLink"},"howToUse":{"description":"A link shown as a button with the benefit on the benefits page.","$ref":"#/components/schemas/BenefitTemplateLink"},"website":{"description":"A link shown as a button with the benefit on the benefits page.","$ref":"#/components/schemas/BenefitTemplateLink"},"other":{"description":"A link shown as a button with the benefit on the benefits page.","$ref":"#/components/schemas/BenefitTemplateLink"}},"additionalProperties":false,"description":"Links shown with the benefit on the benefits page, keyed by purpose."},"initialValue":{"type":["null","number"],"description":"The number of uses a `MultiUse` benefit starts with - the \"5\" in \"3 of 5 left\".","format":"double"},"dataContent":{"type":["null","string"],"description":"Free text copied into each issued benefit's `data.content`, for a pass template or an integration\nto read. Never shown to the holder as such."},"passType":{"type":["null","string"],"description":"Pass template of a standalone wallet pass to create for each issued benefit, alongside the holder's\nown pass. Omit for a benefit that lives only on the holder's pass."},"code":{"description":"How each issued benefit gets the code staff scan or type to redeem it. Omit for a benefit with no\ncode.","$ref":"#/components/schemas/BenefitTemplateCodeSettings"},"removal":{"description":"When a benefit issued from this benefit template leaves the pass. Omit to remove it at end of validity.","$ref":"#/components/schemas/BenefitTemplateRemoval"},"behavior":{"description":"Where a benefit issued from this benefit template is surfaced, and what each surface does with it. Omit for the defaults.","$ref":"#/components/schemas/BenefitTemplateBehavior"},"creationDate":{"oneOf":[{"type":"string","format":"date-time"},{"type":"integer","format":"int64"}],"description":"When the benefit template was created. Set by the server; ignored on write. Null on benefit templates\ncreated before it was recorded. Accepts ISO 8601 date-time string or Unix epoch seconds in request inputs. Responses are serialized as ISO 8601 date-time strings."},"lastModificationDate":{"oneOf":[{"type":"string","format":"date-time"},{"type":"integer","format":"int64"}],"description":"When the benefit template definition last changed. Set by the server on every write; ignored on write. Accepts ISO 8601 date-time string or Unix epoch seconds in request inputs. Responses are serialized as ISO 8601 date-time strings."}},"additionalProperties":false,"description":"The reusable definition of a benefit: what a holder is given each time it is granted to a pass, by an\nautomation, a campaign or a single grant."},"BenefitTemplateValidityMode":{"enum":["fixedDate","duration"],"type":"string","description":"How the end of validity of a benefit issued from a benefit template is computed."},"BenefitType":{"enum":["oneTime","unlimited","multiUse"],"type":"string","description":"How a benefit is consumed, which decides what its movements mean and when it is used up."},"BenefitCategory":{"enum":["other","discount","freeProduct","service","access","giftCard"],"type":"string","description":"What a benefit gives the holder, used to group and label it on the benefits page and in reports."},"BenefitTemplateAppearance":{"type":"object","properties":{"images":{"type":"array","items":{"description":"A single image entry within a benefit template appearance.","$ref":"#/components/schemas/BenefitTemplateImage"},"description":"The images, at most one per slot; where a slot is named twice the last entry wins."}},"additionalProperties":false,"description":"The images a benefit template gives each benefit it issues."},"BenefitTemplateImage":{"required":["slot","url"],"type":"object","properties":{"slot":{"description":"Where the image is used: `main` for the headline visual, `thumbnail` for compact lists.","$ref":"#/components/schemas/BenefitImageSlot"},"url":{"description":"The image, per language. Each value is an `http`/`https` address, or the name of an image\nuploaded to this benefit template (e.g. `hero.png`).","$ref":"#/components/schemas/BenefitTemplateLocalizedString"}},"additionalProperties":false,"description":"A single image entry within a benefit template appearance."},"BenefitImageSlot":{"enum":["main","thumbnail"],"type":"string","description":"The image slots a benefit can fill."},"BenefitTemplateLocalizedString":{"required":["default"],"type":"object","properties":{"default":{"minLength":1,"type":"string","description":"The text shown to a holder whose language has no entry in Neo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateLocalizedString.Localizations."},"localizations":{"type":["null","object"],"additionalProperties":{"type":"string"},"description":"Per-language overrides, keyed by language code (e.g. `fr`, `en-US`)."}},"additionalProperties":false,"description":"A string with a mandatory default value and optional per-language overrides."},"BenefitTemplateContent":{"type":"object","properties":{"title":{"description":"The benefit's name as the holder sees it, on the benefits page and as a wallet pass field. Required\non create; a benefit without one is shown as \"Untitled benefit\".","$ref":"#/components/schemas/BenefitTemplateLocalizedString"},"description":{"description":"What the benefit gives and how to use it, shown on the benefits page and, when the behaviour asks for\nit, on the back of the wallet pass.","$ref":"#/components/schemas/BenefitTemplateLocalizedString"}},"additionalProperties":false,"description":"The holder-facing texts of a benefit template."},"BenefitTemplateLink":{"required":["link"],"type":"object","properties":{"title":{"description":"The button label. At most 100 characters per language.","$ref":"#/components/schemas/BenefitTemplateLocalizedString"},"link":{"type":"string","description":"The address the button opens: an absolute `https` URI.","format":"uri"}},"additionalProperties":false,"description":"A link shown as a button with the benefit on the benefits page."},"BenefitTemplateCodeSettings":{"type":"object","properties":{"format":{"description":"How the code is rendered to the holder: a barcode symbology, or `raw` for text only.","$ref":"#/components/schemas/BenefitCodeFormat"},"valueMode":{"description":"Where the code value comes from: `Shared` uses Neo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateCodeSettings.Value for every holder,\n`Autogenerated` draws a random one per benefit from Neo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateCodeSettings.Pattern, `Custom` runs\nNeo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateCodeSettings.Script. Omit for no code.","$ref":"#/components/schemas/BenefitTemplateCodeValueMode"},"value":{"type":["null","string"],"description":"The code every holder gets, e.g. a promotion code typed at checkout. Required when\nNeo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateCodeSettings.ValueMode is `Shared`."},"pattern":{"description":"Shape of the random code drawn for each benefit. Used when Neo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateCodeSettings.ValueMode is\n`Autogenerated`; omitted, a 10-character upper-case alphanumeric code is drawn.","$ref":"#/components/schemas/BenefitTemplateCodePattern"},"script":{"type":["null","string"],"description":"Body of the JavaScript function that returns the code, without its wrapper, e.g.\n`return \"X-\" + Date.now();`. Required when Neo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateCodeSettings.ValueMode is `Custom`."}},"additionalProperties":false,"description":"How each benefit issued from this benefit template gets its code, and how the code is rendered."},"BenefitCodeFormat":{"enum":["ean13","code128","qrCode","pdf417","aztec","dataMatrix","code39","raw"],"type":"string","description":"How a benefit's code is rendered to the holder, and so what the till or the Pass Scanner scans."},"BenefitTemplateCodeValueMode":{"enum":["shared","autogenerated","custom"],"type":"string","description":"Where the code of a benefit issued from a benefit template comes from."},"BenefitTemplateCodePattern":{"type":"object","properties":{"length":{"type":"integer","description":"Number of random characters, prefix and suffix excluded. Between the charset's minimum (Numeric 9,\nAlpha 7, Hex 8, Alphanumeric 6) and 64.","format":"int32"},"charset":{"description":"The characters the random part is drawn from. `ean13` requires `Numeric`.","$ref":"#/components/schemas/BenefitTemplateCodeCharset"},"prefix":{"type":["null","string"],"description":"Fixed text placed before the random part, e.g. a campaign marker. Digits only for `ean13`."},"suffix":{"type":["null","string"],"description":"Fixed text placed after the random part. Digits only for `ean13`."},"uppercase":{"type":"boolean","description":"Whether letters in the random part are upper-case (default) or lower-case. Prefix and suffix are kept as written."}},"additionalProperties":false,"description":"The shape of a randomly drawn code."},"BenefitTemplateCodeCharset":{"enum":["alphanumeric","numeric","alpha","hex"],"type":"string","description":"The characters the random part of an autogenerated code is drawn from."},"BenefitTemplateRemoval":{"type":"object","properties":{"mode":{"description":"Rule used to compute the benefit's deletion date.","$ref":"#/components/schemas/BenefitTemplateRemovalMode"},"days":{"maximum":3650,"minimum":1,"type":["null","integer"],"description":"How many days an expired benefit stays visible on the pass, shown as expired. Required when\nNeo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateRemoval.Mode is `AfterEndOfValidity`, dropped otherwise.","format":"int32"},"date":{"oneOf":[{"type":"string","format":"date-time"},{"type":"integer","format":"int64"}],"description":"The instant every issued benefit leaves the pass. Required when Neo.Runtime.Benefit.Catalog.IBenefitTemplateCatalog.BenefitTemplateRemoval.Mode is\n`FixedDate`, dropped otherwise. Accepts ISO 8601 date-time string or Unix epoch seconds in request inputs. Responses are serialized as ISO 8601 date-time strings."}},"additionalProperties":false,"description":"When the benefit issued from this benefit template is removed from the pass."},"BenefitTemplateRemovalMode":{"enum":["never","endOfValidity","afterEndOfValidity","fixedDate"],"type":"string","description":"How the deletion date of an issued benefit is derived."},"BenefitTemplateBehavior":{"type":"object","properties":{"mode":{"type":["null","array"],"items":{"description":"Where a benefit is shown and what each surface does with it.","$ref":"#/components/schemas/BenefitBehaviorMode"},"description":"The behaviours an issued benefit carries, one entry per behaviour."}},"additionalProperties":false,"description":"Where a benefit issued from the benefit template is surfaced, and what each surface does with it."},"BenefitBehaviorMode":{"enum":["none","showOnBenefitListPage","showOnPassScanner","redeemOnScan","useMainImageAsWalletImage","addDescriptionAsBackField"],"type":"string","description":"Where a benefit is shown and what each surface does with it."},"ProblemDetails":{"type":"object","properties":{"type":{"type":["null","string"]},"title":{"type":["null","string"]},"status":{"type":["null","integer"],"format":"int32"},"detail":{"type":["null","string"]},"instance":{"type":["null","string"]}},"additionalProperties":{}},"HttpValidationProblemDetails":{"type":"object","allOf":[{"$ref":"#/components/schemas/ProblemDetails"}],"properties":{"errors":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}},"additionalProperties":{}}}},"paths":{"/api/{tenantId}/admin/benefitTemplates/{id}":{"put":{"tags":["BenefitTemplates"],"summary":"Update benefit template","description":"Benefits already issued keep what they were given unless updateBenefits is set: then every live, redeemable benefit is rewritten from the new definition after the response,\nreplacing any edit made on that benefit (movements, creation date and code are kept), and the passes showing them are updated.","parameters":[{"name":"id","in":"path","description":"Benefit template id.","required":true,"schema":{"type":"string"}},{"name":"updateBenefits","in":"query","description":"Also rewrite the live benefits issued from this template.","schema":{"type":"boolean"}},{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Updated template. The route id wins over the body.","content":{"application/json":{"schema":{"description":"The reusable definition of a benefit: what a holder is given each time it is granted to a pass, by an\nautomation, a campaign or a single grant.","$ref":"#/components/schemas/BenefitTemplate"}},"text/json":{"schema":{"description":"The reusable definition of a benefit: what a holder is given each time it is granted to a pass, by an\nautomation, a campaign or a single grant.","$ref":"#/components/schemas/BenefitTemplate"}},"application/*+json":{"schema":{"description":"The reusable definition of a benefit: what a holder is given each time it is granted to a pass, by an\nautomation, a campaign or a single grant.","$ref":"#/components/schemas/BenefitTemplate"}}},"required":true},"responses":{"200":{"description":"Benefit template updated.","content":{"text/plain":{"schema":{"description":"The reusable definition of a benefit: what a holder is given each time it is granted to a pass, by an\nautomation, a campaign or a single grant.","$ref":"#/components/schemas/BenefitTemplate"}},"application/json":{"schema":{"description":"The reusable definition of a benefit: what a holder is given each time it is granted to a pass, by an\nautomation, a campaign or a single grant.","$ref":"#/components/schemas/BenefitTemplate"}},"text/json":{"schema":{"description":"The reusable definition of a benefit: what a holder is given each time it is granted to a pass, by an\nautomation, a campaign or a single grant.","$ref":"#/components/schemas/BenefitTemplate"}}}},"400":{"description":"Invalid payload, or updateBenefits while the template changes its pass template.","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"401":{"description":"The caller is not authenticated.","content":{"application/problem+json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"403":{"description":"The caller lacks the <c>tenant.configuration.benefitTemplate:write</c> scope.","content":{"application/problem+json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"404":{"description":"Benefit template not found.","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"409":{"description":"Another template write is in progress or landed first: reload and retry.","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"429":{"description":"Over 1200 requests per minute to this endpoint for the tenant (default limit); retry after <c>Retry-After</c>.","headers":{"Retry-After":{"description":"Seconds to wait before retrying. Sent when the limiter knows it.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}}}}}}
```

## Delete benefit template

> Refused while a benefit issued from it is still live (wait for expiry or delete those benefits) or an enabled automation grants it.

```json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"BenefitTemplates"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"security":[{"admin-bearer":["tenant.configuration.benefitTemplate:write"]},{"apiKey":[]}],"components":{"securitySchemes":{"admin-bearer":{"type":"oauth2","flows":{"implicit":{"authorizationUrl":"https://auth.neostore.cloud/authorize?audience=https://app.neostore.cloud/api/","scopes":{}}}},"apiKey":{"type":"apiKey","name":"X-API-KEY","in":"header"}},"schemas":{"ProblemDetails":{"type":"object","properties":{"type":{"type":["null","string"]},"title":{"type":["null","string"]},"status":{"type":["null","integer"],"format":"int32"},"detail":{"type":["null","string"]},"instance":{"type":["null","string"]}},"additionalProperties":{}},"HttpValidationProblemDetails":{"type":"object","allOf":[{"$ref":"#/components/schemas/ProblemDetails"}],"properties":{"errors":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}},"additionalProperties":{}}}},"paths":{"/api/{tenantId}/admin/benefitTemplates/{id}":{"delete":{"tags":["BenefitTemplates"],"summary":"Delete benefit template","description":"Refused while a benefit issued from it is still live (wait for expiry or delete those benefits) or an enabled automation grants it.","parameters":[{"name":"id","in":"path","description":"Benefit template id.","required":true,"schema":{"type":"string"}},{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Benefit template deleted."},"400":{"description":"Invalid benefit template id.","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"401":{"description":"The caller is not authenticated.","content":{"application/problem+json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"403":{"description":"The caller lacks the <c>tenant.configuration.benefitTemplate:write</c> scope.","content":{"application/problem+json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"404":{"description":"Benefit template not found.","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"409":{"description":"Still has live benefits or is granted by an enabled automation, or another template write is in progress.","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"429":{"description":"Over 1200 requests per minute to this endpoint for the tenant (default limit); retry after <c>Retry-After</c>.","headers":{"Retry-After":{"description":"Seconds to wait before retrying. Sent when the limiter knows it.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}}}}}}
```

## Upload benefit template image

> Returns the \`path\` to store in the template's appearance fields. File name: starts with a letter or digit, only letters, digits, \`-\` and \`\_\`, ending in \`.png\`, \`.jpg\`, \`.jpeg\`, \`.gif\` or \`.webp\`;\
> the same name replaces the image. Content must match the extension.

```json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"BenefitTemplates"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"security":[{"admin-bearer":["tenant.configuration.benefitTemplate:write"]},{"apiKey":[]}],"components":{"securitySchemes":{"admin-bearer":{"type":"oauth2","flows":{"implicit":{"authorizationUrl":"https://auth.neostore.cloud/authorize?audience=https://app.neostore.cloud/api/","scopes":{}}}},"apiKey":{"type":"apiKey","name":"X-API-KEY","in":"header"}},"schemas":{"BenefitTemplateImageInfo":{"type":"object","properties":{"path":{"type":"string","description":"Image path, `public/benefitTemplates/{id}/{name}`: the value to put in the benefit template's\n`appearance.images[].url`. The bare file name is accepted there too."},"name":{"type":"string","description":"The file name as stored, e.g. `hero.png`; uploading the same name again replaces the image."}},"additionalProperties":false,"description":"Holds the path and file name of a benefit template image."},"ProblemDetails":{"type":"object","properties":{"type":{"type":["null","string"]},"title":{"type":["null","string"]},"status":{"type":["null","integer"],"format":"int32"},"detail":{"type":["null","string"]},"instance":{"type":["null","string"]}},"additionalProperties":{}},"HttpValidationProblemDetails":{"type":"object","allOf":[{"$ref":"#/components/schemas/ProblemDetails"}],"properties":{"errors":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}},"additionalProperties":{}}}},"paths":{"/api/{tenantId}/admin/benefitTemplates/{id}/images":{"post":{"tags":["BenefitTemplates"],"summary":"Upload benefit template image","description":"Returns the `path` to store in the template's appearance fields. File name: starts with a letter or digit, only letters, digits, `-` and `_`, ending in `.png`, `.jpg`, `.jpeg`, `.gif` or `.webp`;\nthe same name replaces the image. Content must match the extension.","parameters":[{"name":"id","in":"path","description":"Benefit template id.","required":true,"schema":{"type":"string"}},{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","description":"Image (multipart/form-data), at most 8 MB.","format":"binary"}}},"encoding":{"file":{"style":"form"}}}}},"responses":{"200":{"description":"Image uploaded; returns the image path.","content":{"text/plain":{"schema":{"description":"Holds the path and file name of a benefit template image.","$ref":"#/components/schemas/BenefitTemplateImageInfo"}},"application/json":{"schema":{"description":"Holds the path and file name of a benefit template image.","$ref":"#/components/schemas/BenefitTemplateImageInfo"}},"text/json":{"schema":{"description":"Holds the path and file name of a benefit template image.","$ref":"#/components/schemas/BenefitTemplateImageInfo"}}}},"400":{"description":"Missing or empty file, over 8 MB, invalid id or file name, or content not matching the extension.","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"401":{"description":"The caller is not authenticated.","content":{"application/problem+json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"403":{"description":"The caller lacks the <c>tenant.configuration.benefitTemplate:write</c> scope.","content":{"application/problem+json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"404":{"description":"Benefit template not found.","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"413":{"description":"The request body is larger than 8 MB.","content":{"application/problem+json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"429":{"description":"Over 1200 requests per minute to this endpoint for the tenant (default limit); retry after <c>Retry-After</c>.","headers":{"Retry-After":{"description":"Seconds to wait before retrying. Sent when the limiter knows it.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}}}}}}
```

## GET /api/{tenantId}/admin/benefitTemplates/{id}/images/{fileName}

> Get benefit template image

```json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"BenefitTemplates"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"security":[{"admin-bearer":["tenant.configuration.benefitTemplate:read"]},{"apiKey":[]}],"components":{"securitySchemes":{"admin-bearer":{"type":"oauth2","flows":{"implicit":{"authorizationUrl":"https://auth.neostore.cloud/authorize?audience=https://app.neostore.cloud/api/","scopes":{}}}},"apiKey":{"type":"apiKey","name":"X-API-KEY","in":"header"}},"schemas":{"ProblemDetails":{"type":"object","properties":{"type":{"type":["null","string"]},"title":{"type":["null","string"]},"status":{"type":["null","integer"],"format":"int32"},"detail":{"type":["null","string"]},"instance":{"type":["null","string"]}},"additionalProperties":{}},"HttpValidationProblemDetails":{"type":"object","allOf":[{"$ref":"#/components/schemas/ProblemDetails"}],"properties":{"errors":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}},"additionalProperties":{}}}},"paths":{"/api/{tenantId}/admin/benefitTemplates/{id}/images/{fileName}":{"get":{"tags":["BenefitTemplates"],"summary":"Get benefit template image","parameters":[{"name":"id","in":"path","description":"Benefit template id.","required":true,"schema":{"type":"string"}},{"name":"fileName","in":"path","description":"Image file name, e.g. `hero.png`.","required":true,"schema":{"type":"string"}},{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Image bytes returned."},"400":{"description":"Invalid benefit template id or file name.","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"401":{"description":"The caller is not authenticated.","content":{"application/problem+json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"403":{"description":"The caller lacks the <c>tenant.configuration.benefitTemplate:read</c> scope.","content":{"application/problem+json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"404":{"description":"Image not found.","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"429":{"description":"Over 1200 requests per minute to this endpoint for the tenant (default limit); retry after <c>Retry-After</c>.","headers":{"Retry-After":{"description":"Seconds to wait before retrying. Sent when the limiter knows it.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}}}}}}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.thewalletcrew.io/api-reference/tenant-configuration/benefit-templates.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
