# Write your first recipe

At the end of this tutorial, the Nimbus CRM API has an operation that creates a company and its first contact in a single call. Without it, an agent makes two calls: it creates the company with `POST /api/companies`, reads the new `id` from the response, and passes it as `company_id` to `POST /api/contacts`.

In this tutorial, you:

- [Draft the recipe](#draft-the-recipe)
- [Read and edit the code](#read-and-edit-the-code)
- [Test the recipe](#test-the-recipe)
- [Accept and publish](#accept-and-publish)

## Before you begin

- The Nimbus CRM API and its **Staging** connection from [Analyze your first API](https://docs.faustine.ai/apis/analyze-your-first-api/).
- The keys of the two operations the recipe calls. In the **Operations** tab, find the operations for `POST /api/companies` and `POST /api/contacts` and note their keys. This tutorial assumes `companies.create` and `contacts.create`.

## Draft the recipe

The analysis of Nimbus CRM proposes a recipe for this same job, `companies.createWithContact`, in the **Recipes** tab. This tutorial writes one from a description so that you see every step. To take the proposed one, see [Accept or reject a proposed recipe](https://docs.faustine.ai/apis/review-proposed-recipes/).

1. In the portal, go to [**APIs**](https://auth.faustine.ai/go?to=%2Fintegrations%2Fapis) and select **Nimbus CRM**.
2. Select the **Recipes** tab, then **New recipe**.
3. Select **AI-Assisted**.
4. Enter what the recipe does:

   ```text
   Create a company and its first contact: create the company from a name, then create a contact with a first name, last name and email in that company. Return both ids.
   ```

5. Select **Create recipe**.

Faustine picks the operations, writes the code and the schemas, and validates the result. The dialog shows what it reads and writes as it works. When it finishes, the recipe editor opens on the new recipe, with the status **Proposed**.

## Read and edit the code

The editor opens on the **Code** file. The first lines are the summary that agents read and an optional description. The script follows.

1. Compare the script with this one. The names of your inputs can differ.

   ```js
   const company = await sdk.nimbuscrm.companiesCreate({ name: input.companyName })
   const contact = await sdk.nimbuscrm.contactsCreate({
     first_name: input.firstName,
     last_name: input.lastName,
     email: input.email,
     company_id: company.id,
   })
   return { companyId: company.id, contactId: contact.id }
   ```

2. Check the two calls. `sdk.nimbuscrm` is the API's namespace, and each function is an operation key in camel case: `companies.create` is `companiesCreate`. The argument is the operation's input, with the field names of its request schema.
3. Check the `return`. It is what the agent receives. Return the ids so that the agent can refer to the new records in its next call.
4. Select **Input schema**. Each field the script reads from `input` is a property, and the ones the recipe cannot work without are in `required`.
5. If you changed the code or a schema, select **Validate**, then **Save**.

**Validate** checks the code without running it and reports any call that matches no operation of the API. **Save** runs the same check and does not store code that fails it.

## Test the recipe

1. Select **Test** in the editor's side bar.
2. In **Connection**, select **Staging**.
3. In **Input**, enter values for the recipe's fields. With the schema of the script in this tutorial:

   ```json
   {
     "companyName": "Acme Robotics",
     "firstName": "Dana",
     "lastName": "Reyes",
     "email": "dana.reyes@acmerobotics.example"
   }
   ```

4. Select **Run**.

> **Warning:** The test makes real calls. It creates a company and a contact in the Nimbus CRM instance behind **Staging**.

> **Checkpoint:** **Result** shows the two ids. **Steps** lists two calls, the company first and the contact second, both successful. In Nimbus CRM, the company page of Acme Robotics shows Dana Reyes as a contact.

## Accept and publish

1. In the recipe editor, select **Accept**, then confirm. The dialog shows that the recipe runs as a write, because the operations it calls are writes.
2. Select **Recipes** to go back to the API page.
3. In the API's header, select **Publish**, then confirm.

The **Operations** tab now lists the recipe as a composite operation, next to the operations the analysis found.

## What you built

The Nimbus CRM API has a composite operation that creates a company and a contact in one call, in the version you published. A gateway serves it once the operation is exposed in the gateway's **Operations** tab.

## Next steps

- [Choose which operations are exposed](https://docs.faustine.ai/agent-gateway/choose-operations/): expose the recipe in a gateway.
- [Recipes](https://docs.faustine.ai/apis/recipes/): everything a recipe's code can use.
- [Import recipes from client code](https://docs.faustine.ai/apis/import-recipes/): get proposals from the Nimbus CRM front end.
- [Accept or reject a proposed recipe](https://docs.faustine.ai/apis/review-proposed-recipes/): review what the analysis and imports propose.
