# Product

URL: /define/product · Id: `term:product`

> What a Startup sells; an API Product is one whose Definition declares operations.

A Product is what a Startup sells; an API Product is one whose [Definition](/reference/concepts#definition) declares operations.

## Parts
| Field | Type | Required | What it is |
| --- | --- | --- | --- |
| `startup` | `string` | Yes | The home Domain of the Startup that sells the API: its namespace, and the host every Interface answers on. |
| `product` | `string` | Yes | The key of the API Product within its Startup. |
| `name` | `string` | Yes | The name every Interface prints. |
| `description` | `string` | Yes | What the API answers, in one line. |
| `version` | `string` | Yes | The version every Interface prints. |
| `currency` | `"USD"` | Yes | The currency of every posted rate. |
| `free` | `integer` | No | The calls a month that cost nothing; it is stored on the Offer. |
| `requiresKey` | `boolean` | No | Whether every call needs a Key; it is stored on the Offer. |
| `tags` | `{ name, description }[]` | No | Groups of operations, for the docs and OpenAPI. |
| `operations` | `Operation[]` | Yes | Every operation the API serves, at least one. |

## Example
```json title="openhours.example: the Definition"
{
  "startup": "openhours.example",
  "product": "openhours",
  "name": "Openhours",
  "description": "Opening hours for places, by place id.",
  "version": "1.0.0",
  "currency": "USD",
  "free": 1000,
  "requiresKey": true,
  "operations": [
    {
      "verb": "findPlaces",
      "method": "GET",
      "path": "/places",
      "summary": "Places in one city",
      "description": "Lists the places Openhours holds in one city, by the city name, each with its place id.",
      "params": [
        {
          "name": "city",
          "in": "query",
          "type": "string",
          "required": true,
          "description": "The city name",
          "example": "Lisbon"
        }
      ],
      "returns": {
        "type": "array",
        "items": {
          "type": "object",
          "properties": { "placeId": { "type": "string" }, "name": { "type": "string" } }
        }
      },
      "example": {
        "input": { "city": "Lisbon" },
        "output": [{ "placeId": "pl_4821", "name": "Cafe Alfama" }]
      },
      "price": 0.002,
      "run": { "kind": "list", "collection": "places", "filters": ["city"] }
    },
    {
      "verb": "getHours",
      "method": "GET",
      "path": "/places/{placeId}/hours",
      "summary": "The opening hours of one place",
      "description": "Answers the weekly opening hours of one place, in the place's own timezone.",
      "params": [
        {
          "name": "placeId",
          "in": "path",
          "type": "string",
          "required": true,
          "description": "The place id",
          "example": "pl_4821"
        }
      ],
      "returns": {
        "type": "object",
        "properties": {
          "placeId": { "type": "string" },
          "timezone": { "type": "string" },
          "open": { "type": "array" }
        }
      },
      "example": {
        "input": { "placeId": "pl_4821" },
        "output": {
          "placeId": "pl_4821",
          "timezone": "Europe/Lisbon",
          "open": [{ "day": "mon", "from": "09:00", "to": "18:00" }]
        }
      },
      "price": 0.002,
      "run": { "kind": "get", "collection": "hours", "key": "placeId" }
    }
  ]
}
```