# Offer methods: accept, grant, publish, subscribe

URL: /code/sdk/offer/verbs · Id: `page:code/sdk/offer/verbs`

> The Offer Verbs accept, grant, publish, subscribe as typed SDK methods, with inputs, result, refusals and an example.

Reference for [Offer](/business/nouns/offer), one group of [Offer methods](/code/sdk/offer).

### Offer.accept
Accept records that a party takes an Offer, which makes that party a Customer of the Startup. [Verb page](/business/nouns/offer/accept?interface=sdk).

```ts
interface OfferVerbs {
  accept(input: OfferAcceptInput, options?: SB.CallOptions): SB.Call<OfferAcceptOutput>
}
```

Emits [`Offer.accepted`](/business/events/Offer.accepted).

**Inputs**

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `offer` | [Offer](/business/nouns/offer) | Yes | The Offer to accept. |
| `party` | `string` | Yes | The person or organization accepting. |

**Returns**

| Output | Type | Required | Description |
| --- | --- | --- | --- |
| `customer` | [Customer](/business/nouns/customer) | Yes | The Customer the party is or becomes. |
| `offer` | [Offer](/business/nouns/offer) | Yes | The Offer accepted. |

**Refuses when**

| Check | Error | Fix | Then call |
| --- | --- | --- | --- |
| The operation is part of an Offer the caller has not accepted or paid for. | [`payment-required`](/code/api/errors/payment-required) | Accept the Offer named in the response, then retry the call. | None. |
| The key is valid, but its scopes do not allow this operation. | [`forbidden`](/code/api/errors/forbidden) | Use a key whose scopes cover the operation, or ask an owner of the namespace to grant them. | None. |
| The record is not in a state that allows this Verb, so the call is refused. | [`refused`](/code/api/errors/refused) | Read the record, run the Verb that moves it to an allowed state, then retry. | None. |

**Example**

```ts
import { $ } from 'startup-builder'

const { customer, offer } = await $.Offer.accept({ offer: 'offer_2hzYe1ERo0', party: 'Pinecrest Homes' })
```

### Offer.grant
Grant adds an Entitlement to an Offer: a Verb its Customers may call, optionally bounded by a Limit. [Verb page](/business/nouns/offer/grant?interface=sdk).

```ts
interface OfferVerbs {
  grant(input: OfferGrantInput, options?: SB.CallOptions): SB.Call<OfferGrantOutput>
}
```

Emits [`Offer.granted`](/business/events/Offer.granted).

**Inputs**

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `offer` | [Offer](/business/nouns/offer) | Yes | The Offer that grants it. |
| `verb` | [Verb](/business/nouns/verb) | Yes | The Verb its Customers may call, as `Noun.verb`. |
| `limit` | [Limit](/business/nouns/limit) | No | The Limit that bounds it. Unset: a feature, called as often as the Customer likes. |

**Returns**

| Output | Type | Required | Description |
| --- | --- | --- | --- |
| `entitlement` | [Entitlement](/business/nouns/entitlement) | Yes | The new Entitlement, granted by the Offer. |
| `offer` | [Offer](/business/nouns/offer) | Yes | The Offer, with the Entitlement added. |

**Refuses when**

| Check | Error | Fix | Then call |
| --- | --- | --- | --- |
| The key is valid, but its scopes do not allow this operation. | [`forbidden`](/code/api/errors/forbidden) | Use a key whose scopes cover the operation, or ask an owner of the namespace to grant them. | None. |

**Example**

```ts
import { $ } from 'startup-builder'

const { entitlement, offer } = await $.Offer.grant({ offer: 'offer_2hzYe1ERo0', verb: 'verb_hlkWBvrAyZ' })
```

### Offer.publish
Publish makes an Offer available for parties to accept. [Verb page](/business/nouns/offer/publish?interface=sdk).

```ts
interface OfferVerbs {
  publish(input: OfferPublishInput, options?: SB.CallOptions): SB.Call<Offer>
}
```

Emits [`Offer.published`](/business/events/Offer.published).

**Inputs**

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `offer` | [Offer](/business/nouns/offer) | Yes | The Offer to publish. |

**Returns**

| Output | Type | Required | Description |
| --- | --- | --- | --- |
| `offer` | [Offer](/business/nouns/offer) | Yes | The Offer, now open to accept. |

**Refuses when**

| Check | Error | Fix | Then call |
| --- | --- | --- | --- |
| A Service Offer promises a remedy or a pricing basis that its Service’s checks cannot back. | [`contract-unsupported`](/code/api/errors/contract-unsupported) | Add a stronger check to the Service’s steps, or offer a cheaper remedy or basis, then publish again. | None. |
| The key is valid, but its scopes do not allow this operation. | [`forbidden`](/code/api/errors/forbidden) | Use a key whose scopes cover the operation, or ask an owner of the namespace to grant them. | None. |
| The record is not in a state that allows this Verb, so the call is refused. | [`refused`](/code/api/errors/refused) | Read the record, run the Verb that moves it to an allowed state, then retry. | None. |
| The median Customer’s Cost leaves less than the Startup’s target margin at this Price. | [`below-contribution-floor`](/code/api/errors/below-contribution-floor) | Raise the Price to the floor the error names, or grant fewer Entitlements. | [Offer.update](/business/nouns/offer/update) |

**Example**

```ts
import { $ } from 'startup-builder'

const offer = await $.Offer.publish({ offer: 'offer_2hzYe1ERo0' })
```

### Offer.subscribe
Subscribe accepts a recurring Offer as a Subscription that renews each period until it ends. [Verb page](/business/nouns/offer/subscribe?interface=sdk).

```ts
interface OfferVerbs {
  subscribe(input: OfferSubscribeInput, options?: SB.CallOptions): SB.Call<OfferSubscribeOutput>
}
```

Emits [`Offer.subscribed`](/business/events/Offer.subscribed).

**Inputs**

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `offer` | [Offer](/business/nouns/offer) | Yes | The recurring Offer. |
| `quantity` | `integer` | No | Seats or units. Defaults to 1. |
| `promotionCode` | `string` | No | A promotion code the buyer typed; applies its Coupon for the Coupon’s duration. |

**Returns**

| Output | Type | Required | Description |
| --- | --- | --- | --- |
| `subscription` | [Subscription](/business/nouns/subscription) | Yes | The new Subscription. |
| `offer` | [Offer](/business/nouns/offer) | Yes | The Offer subscribed to. |

**Refuses when**

| Check | Error | Fix | Then call |
| --- | --- | --- | --- |
| The input does not match the schema of the operation. | [`invalid-input`](/code/api/errors/invalid-input) | Read the schema of the operation, then send every required field with the right type. | None. |
| The operation is part of an Offer the caller has not accepted or paid for. | [`payment-required`](/code/api/errors/payment-required) | Accept the Offer named in the response, then retry the call. | [Offer.accept](/business/nouns/offer/accept) |
| The key is valid, but its scopes do not allow this operation. | [`forbidden`](/code/api/errors/forbidden) | Use a key whose scopes cover the operation, or ask an owner of the namespace to grant them. | None. |
| The record is not in a state that allows this Verb, so the call is refused. | [`refused`](/code/api/errors/refused) | Read the record, run the Verb that moves it to an allowed state, then retry. | None. |

**Example**

```ts
import { $ } from 'startup-builder'

const { subscription, offer } = await $.Offer.subscribe({ offer: 'offer_2hzYe1ERo0' })
```