# Quick Start

Coevera (formerly Pipeliner CRM) is Sales CRM. You can use our API to build integrations with your systems with [**REST API** ](http://pipeliner-api-doc.s3-website-eu-west-1.amazonaws.com/latest/rest/space/index.html)or [**GraphQL API**](http://pipeliner-api-doc.s3-website-eu-west-1.amazonaws.com/latest/graphql/space/index.html)**.**

{% embed url="<https://www.youtube.com/watch?v=OPuP9xR8zGQ>" %}

## Choose your preferred API

The Coevera API can be accessed with [**REST API** ](http://pipeliner-api-doc.s3-website-eu-west-1.amazonaws.com/latest/rest/space/index.html)or [**GraphQL API**](http://pipeliner-api-doc.s3-website-eu-west-1.amazonaws.com/latest/graphql/space/index.html)

**Rest API download:** [**openapi.json**](http://pipeliner-api-doc.s3-website-eu-west-1.amazonaws.com/latest/rest/space/openapi.json)

**GraphQL download:** [**GraphQL.json**](https://crm.pipelinersales.com/api/v100/app/graphql/schema.json)

## Obtain API Keys&#x20;

[**Create the API application**](/api-docs/overview/authentication) and make the first request to Coevera.

## Learn the main Concepts of API

In the [**Core API concepts,** ](/api-docs/core-api-concepts/understanding-the-crm-concept)you can find various ways of working with the Coevera API that can help you build efficient integrations

## Learn About Coevera API

Read through the step-by-step [**tutorials** ](/api-docs/tutorials-and-articles/create-account)where you can find basic business concepts of how Coevera works


# About the API

## API formats

The Coevera API endpoints are documented in [**REST API** ](https://pipeliner.stoplight.io/docs/api-docs)or [**GraphQL API**](http://pipeliner-api-doc.s3-website-eu-west-1.amazonaws.com/latest/graphql/space/index.html) reference.

### Download API endpoints

You can download the Rest API JSON in Open Api 3.0.0 format and import it to the tools like [**Postman**](https://www.postman.com/)**,** [**Insomnia**](https://insomnia.rest/). In case you are using GraphQL, you can import GraphQL Schema to the [**Insomnia**](https://insomnia.rest/) as well

**Rest API download:** [**openapi.json**](http://pipeliner-api-doc.s3-website-eu-west-1.amazonaws.com/latest/rest/space/openapi.json)

**GraphQL Schema download:** [**GraphQL.json**](https://crm.pipelinersales.com/api/v100/app/graphql/schema.json)

## API URL Syntax

For Rest API or GraphQL API the URL Syntax stays the same

**Rest API BaseURL Format**

```
https://us-east.coevera.com/api/v100/rest/spaces/<space_id>/..
```

![](/files/7Z1I2KHFZNholuqOF5uw)

**GraphQL API BaseURL Format**

```
https://<SERVICE_URL>/api/v100/app/space/<SPACE_ID>/graphql/public
```

\
The BaseURL is divided into the following three sections:

#### **Service URL**

The Service URL of Coevera APIs is generated dynamically at the time of creating an application. This usually depends on the geographical area where the space is located. For the Service URL, you need to have an active [**API application**](/api-docs/overview/authentication)**.**

#### **Space and Space ID**

Space ID is the identifier of the space where you are trying to connect. Space ID can be found in the process of obtaining [**API Access**](/api-docs/overview/authentication)**.**

#### **Endpoints**

Endpoints are the API methods combined with the corresponding entity. <br>

**Example of final BaseURL**

```
https://us-east.coevera.com/api/v100/rest/spaces/nv1_example_space
```


# Authentication

### Obtain API key

Coevera API is using Basic authentication which consists of **username** and **password**. Each team space has its own **Coevera API Keys** which are used as username and password.

In order to obtain your team space **Coevera API Keys** follow these steps:

1\) Sign in to the Coevera space here: [**https://crm.coevera.com**](https://crm.coevera.com/) using your Coevera account.

2\) Select your space and Go to the administration.

![](/files/nDoBAYhka3OVuawNbG2s)

3\) Under the Unit, Users & Roles tab open **Applications**

![](/files/To5x86u5EMXeWFurimbB)

4\) Create a new Application

![](/files/fJ5gU0X1TyTTflTC6OI1)

5\) Click Show API Access

1. **User Name** and **Password** are used for Basic Authentication and are generated only once, so store them carefully
2. **Space ID** and **Service URL** are part of every URL Request. See how the [**requests are formated**](/api-docs/overview/about-the-api)

![](/files/LV80TLUvNDS1PrbXplKj)


# Understanding the CRM Concept

CRM is a technology for managing all your company´s relationships and interactions with existing customers and potential customers. For managing this information Coevera provides CRM users with different objects representation and relationships between them. Coevera calls the main objects **Entities.**&#x20;

### **Entities**

Entities help to map company sales business processes in the CRM. In Coevera, there exist following Entities

![Entities management inside Coevera Application](/files/8nPWt1Rzni377FatOylW)

### Main Entities

* **Accounts** *(*[***Endpoints:***](https://pipeliner.stoplight.io/docs/api-docs/b3A6MjAzNTk4OTA-accounts-list) *{{baseURL}}/entities/Accounts)*
  * accounts stores Company information (industry, company size, contacts). See how to create [**an Account**](/api-docs/tutorials-and-articles/create-account)
* **Contacts** *(*[***Endpoints:*** ](https://pipeliner.stoplight.io/docs/api-docs/b3A6MjAzNjAxMTA-contacts-list)*{{baseURL}}/entities/Contacts)*
  * contacts refer to people who have a relation to a specific Account.  See how to create [**a Contact**](/api-docs/tutorials-and-articles/create-contact)
* **Opportunities** *(*[***Endpoints:***](https://pipeliner.stoplight.io/docs/api-docs/b3A6MjAzNjA0ODY-opportunities-list) *{{baseURL}}/entities/Opportunities)*
  * represents existing or potential business revenue with Contact or Account. Opportunities have to move through several stages in Pipeline. See how to create [**an** **Opportunity**](/api-docs/tutorials-and-articles/create-opportunity)
* **Leads** ([**Endpoints:**](https://pipeliner.stoplight.io/docs/api-docs/b3A6MjAzNjAzNjM-leads-list) *{{baseURL}}/entities/Leads*)
  * represents the potential business to your company
* **Activities**&#x20;
  * Represents Tasks and Appointments together. Tasks are one-time activities that usually don´t have duration. We can refer to Appointments as meeting with duration.
    * **Appointments** *(Endpoint: {{baseURL}}/entities/Appointments)*
    * **Tasks:** *(Endpoint: {{baseURL}}/entities/Tasks)*
* **Products** *(*[***Endpoints***](https://pipeliner.stoplight.io/docs/api-docs/b3A6MjAzNjA1OTg-products-list)*: {{baseURL}}/entities/Products)*
  * Represents physical items that your sales team is selling. See how to create [**Products**](/api-docs/tutorials-and-articles/create-product-product-line-item)
* **Product Line Items** *(*[***Endpoints:*** ](https://pipeliner.stoplight.io/docs/api-docs/b3A6MjAzNjA1MDA-oppty-product-relations-list)*{{baseURL}}/entities/OpptyProductRelations)*
  * *Represents product that is being currently sold by your sales team. Product Line items are direct connections between Opportunity and Physical Product. See how to work with* [***Product Line items***](/api-docs/tutorials-and-articles/create-product-product-line-item)

### **Other data**

* **Notes**
* **Documents** *(*[***Endpoints**:*](https://pipeliner.stoplight.io/docs/api-docs/b3A6MjAzNjAwNzU-cloud-objects-list) *{{baseURL}}/entities/*&#x43;loudObject&#x73;*)*
* **Messages**

{% hint style="info" %}
To get **{{baseURL}}** read [**About the API**](/api-docs/overview/about-the-api)
{% endhint %}

### Creating Relations between entities

Entities in the CRM are **linked between themselves** with relations. Take a look at the **entity-relationship diagram** to understand the connections that can exist.

![](/files/DNd79JlPXj2CdDcad2NT)

### Fields

Fields represent a property of Entity where end-users(salespeople) store information like (Name, Opportunity Value, Industry...). Coevera works with **System Fields** (defined by the Coevera system) and **Custom Fields** (defined by business people). Learn more about [**working with fields**](/api-docs/core-api-concepts/fields)**.**

### Users & Roles & Sales units (Accessing Records)

Users, roles, sales units determine what users can see inside the Coevera application. At the top of the hierarchy is the Role, which includes 0..N users. Those Users can be part of the N Sales Units. To understand how **roles**, **users,** **sales unit** works [**read this article**](https://help.pipelinersales.com/en/articles/2706463-managing-user-roles)**.**

![](/files/SLNscRQQIdGZSPmNIYqK)

#### **Role**

*Api name: **master\_right***

Users are part of the Role. Users can be assigned only to one Role. The role determines what data, features the User can access.

Example of Roles: *Standard Users, Administrators, Salespeople*

{% openapi src="/files/483oBiKgEGR3bPMLT8VK" path="/entities/MasterRights" method="get" %}
[openapi (1).json](https://3470708952-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFpjbhrh1xo0SPAbAc7Ny%2Fuploads%2FOlNVdYj1h5GSxQmLHAjz%2Fopenapi%20\(1\).json?alt=media\&token=4be07353-5170-4a95-9100-4f16545d47b0)
{% endopenapi %}

#### **User**

*Api name: **c*****lient**

Users are real people who have access to the Coevera space. Users usually get a direct invitation to the space from the space admin. The user unique identification is *email\_address.*&#x20;

Users can be assigned to the Entity Records. Users who are assigned to the records are called **Owners.** Owners are required on the majority of entities. Only Leads and Activities can be unassigned (without an Owner).&#x20;

{% hint style="info" %}
Every user has a **default\_unit** attribute. You can use this attribute when creating records in Coevera.&#x20;
{% endhint %}

{% openapi src="/files/483oBiKgEGR3bPMLT8VK" path="/entities/Clients" method="get" %}
[openapi (1).json](https://3470708952-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFpjbhrh1xo0SPAbAc7Ny%2Fuploads%2FOlNVdYj1h5GSxQmLHAjz%2Fopenapi%20\(1\).json?alt=media\&token=4be07353-5170-4a95-9100-4f16545d47b0)
{% endopenapi %}

#### **Sales Unit**

*Api name:* **unit**

Sales units from a business point of view are groups of users with similar traits. Sales units works in the hierarchy. Coevera admin defines this hierarchy based on the business requirements. Sales units can refer to territory, team, business unit.

Example of Sales units: Canada, Europe -> UK, Germany, France

![](/files/plsUe1MreDlsJuo41eld)

{% hint style="info" %}
Every Entity has to be connected with the Sales Unit. Even when the record is Unassigned. It is recommended to use the Client (User) default sales Unit.
{% endhint %}

**System Sales Unit**

The `Company`sales Unit is System Sales Unit. It is always at the top of the hierarchy and you can always assign entity records to this Sales Unit. Company Sales Unit has always attribute `parent:`**`null`**

```json
{
            "is_delete_protected": false,
            "id": "ea33e8fb-9a56-4802-a175-2d1f406af7cf",
            "is_deleted": false,
            "modified": "2019-02-01 13:17:03.495636+00:00",
            "created": "2019-01-30 11:06:54.115137+00:00",
            "parent": null,
            "picture": "https://us-east.coevera.com/api/v100/rest/spaces/nv3_PipelinerDev/entities/CloudObjects/74cc1d77-11d7-455d-9c32-39065f269e1b",
            "name": "Company ",
            "parent_id": null,
            "picture_id": "74cc1d77-11d7-455d-9c32-39065f269e1b",
            "revision": 816
        }
```

{% openapi src="/files/483oBiKgEGR3bPMLT8VK" path="/entities/SalesUnits" method="get" %}
[openapi (1).json](https://3470708952-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFpjbhrh1xo0SPAbAc7Ny%2Fuploads%2FOlNVdYj1h5GSxQmLHAjz%2Fopenapi%20\(1\).json?alt=media\&token=4be07353-5170-4a95-9100-4f16545d47b0)
{% endopenapi %}


# Fields

Fields offer Coevera users the opportunity to add detailed information to the Entities - for example, Account Name, Address, Website, Phone numbers for Accounts and Opportunity Name, Close Date, Value for Opportunities. [**Learn more about** ](https://help.pipelinersales.com/en/articles/2714255-fields-forms)how to manage fields in Coevera

![Manage fields in Administration -> Fields & Forms -> Select Entity -> FieldsS](/files/y1XFgkQeMdnuvpqBXR0R)

{% hint style="info" %}
To view fields inside the Coevera Interface, you need to move the field to the **Entity form**.
{% endhint %}

**System & Custom Fields**

System fields are automatically included in Coevera. These fields can´t be deleted.

Custom fields are defined by business/user. The business can create the fields based on their needs in the Administration.

**Field Properties**

* **Api Field Name** - API name of the field. When working with API this is the name of the field, that you will use in the request/response
* **Type** - Coevera supports several field types (dropdowns, date fields, line inputs etc.)
* **Field name** - Name of the field in the Coevera Application

![](/files/gKoq6CGO5cpBkNmC4G4h)

### Creating & Updating Custom Fields

As a developer, you have an option to create custom fields through API. Not every field can be created through API though. In the table below you can find a list of supported fields.

#### List of Supported fields

| Name                 | Type\_id              |
| -------------------- | --------------------- |
| Single Line text     | input                 |
| Long Text            | text\_area            |
| Dropdown             | dropdown              |
| Checkbox             | checkbox              |
| Multi select checkox | multiselect\_checkbox |
| Radio Button         | radio                 |
| Base Currency        | currency              |
| Multiple Currencies  | currency\_foreign     |
| Date                 | date                  |
| DateTime             | datetime              |
| Float Number         | float                 |
| Integer Number       | integer               |
| Autonumber           | sequence              |
| Url                  | url                   |
| Email                | email                 |
| Phone                | phone                 |

{% openapi src="/files/483oBiKgEGR3bPMLT8VK" path="/entities/Fields" method="post" %}
[openapi (1).json](https://3470708952-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFpjbhrh1xo0SPAbAc7Ny%2Fuploads%2FOlNVdYj1h5GSxQmLHAjz%2Fopenapi%20\(1\).json?alt=media\&token=4be07353-5170-4a95-9100-4f16545d47b0)
{% endopenapi %}

```
POST {{baseUrl}}/entities/Fields
{
    "name": "Dropdown field example",
    "type_id": "dropdown",
    "entity_name": "Account",
    "data_set": [
        {"option_name": "Option 1", "calc_value": 1},
        {"option_name": "Option 2", "calc_value": 2},
        {"option_name": "Option 3", "calc_value": 3},
    ]
}
```

`calc_value -` For **Dropdowns, Multi-select checkbox, Radio** is required. Every option has a value and when this option is used in calculated field, it is calculated with this value. If you don´t plan to use options with calculated fields, you can just use **"1"** for all `calc_values`

`entity_name` - Account, Contact, Lead, Opportunity, Product, LeadOpptyProductRelation (Product Line Items), Task, Appointment, Project

#### Update Existing custom field

For example, when you want to add a new option to the dropdown, you can update the existing custom field

{% openapi src="/files/483oBiKgEGR3bPMLT8VK" path="/entities/Fields/{id}" method="patch" %}
[openapi (1).json](https://3470708952-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFpjbhrh1xo0SPAbAc7Ny%2Fuploads%2FOlNVdYj1h5GSxQmLHAjz%2Fopenapi%20\(1\).json?alt=media\&token=4be07353-5170-4a95-9100-4f16545d47b0)
{% endopenapi %}

```
Patch {{baseUrl}}/entities/<field_id>
{
    "name": "Updated Dropdown field example",
    "data_set": [
        {"id": "123456"}, // id of existing dropdown option 1
        {"id": "654321"}, // id of existing dropdown option 2
        {"id": "456789", "optiona_name": "Updated Option 3"}, // id of existing dropdown option 3
        {"option_name": "New Option 4", "calc_value": 3},  // new dropdown option 4
    ]
}
```

### Get All fields

To retrieve **all** fields use the following endpoint. Every field has a unique identification `api_name`. This is how you can filter fields, that you need to work with

{% openapi src="/files/483oBiKgEGR3bPMLT8VK" path="/entities/Fields" method="get" %}
[openapi (1).json](https://3470708952-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFpjbhrh1xo0SPAbAc7Ny%2Fuploads%2FOlNVdYj1h5GSxQmLHAjz%2Fopenapi%20\(1\).json?alt=media\&token=4be07353-5170-4a95-9100-4f16545d47b0)
{% endopenapi %}

```json
"data": [
        {
            "is_delete_protected": false,
            "has_draft": false,
            "id": "00000001-0001-a001-0040-000000000001",
            "is_deleted": false,
            "modified": "2020-09-21 10:16:11.968255+00:00",
            "created": "2020-09-21 10:16:12.334879+00:00",
            "entity_name": "Task",
            "api_name": "sf_jira_issue_link2",
            "name": "Jira Issue Link",
            "use_lang": 0,
            "column_name": "sf_jira_issue_link2_2",
            "column_source": 3,
       }
]
```

### Get Field Values

To get specific field valuies use a combination of [**API paremeters**](/api-docs/core-api-concepts/api-parameters) and `{{baseURL}}/entities/Fields` endpoint

**Example**

In this example we want to retrieve the values of the dropdown field with api field name `industry_id.` We use `filter`, one of the [**API parameters**](/api-docs/core-api-concepts/api-parameters) to find specific field by `api_name.`

```
GET 
{{baseUrl}}/entities/Fields?expand=data_set&load-only=api_name,data_set.option_name&filter[api_name]=industry_id
```

```
"data": [
        {
            "api_name": "industry_id",
            "data_set": [
                {
                    "option_name": "Accounting"
                },
                {
                    "option_name": "Agriculture"
                },
                {
                    "option_name": "Broadcasting"
                }
                ...
    }
 ]       
                
                
```


# API parameters

API parameters make developers efficient when working with Coevera API. API parameters may vary from endpoint to endpoint.

**Example**

```
{{baseUrl}}/entities/Clients?
include-deleted=true&
first=-8971250&
last=-8971250&
before=true&after=true&
expand=expand=owner,sales_unit,account_relations.account&
order-by=order-by=created,-modified&
load-only=id,default_unit_id&
filter[emai]=john.doe@example.com
```

### List of Query parameters

<table><thead><tr><th width="150">Query parameter Name</th><th>Description</th><th>Endpoint Type</th></tr></thead><tbody><tr><td><strong>validation-level</strong></td><td>Turn offs validation on API requests</td><td>*.Create, *.Update, *.Delete</td></tr><tr><td><strong>after</strong></td><td>Cursor, Used for Pagination of long lists. See <a href="/pages/UNu1kxh6KZiMv2ORRdfp"><strong>pagination</strong></a></td><td>*.List</td></tr><tr><td><strong>before</strong></td><td>Cursor, Used for Pagination of long lists. See <a href="/pages/UNu1kxh6KZiMv2ORRdfp"><strong>pagination</strong></a></td><td>*.List</td></tr><tr><td><strong>expand</strong></td><td>Expand related entity, to get immediate overview</td><td>*.List, *.Get</td></tr><tr><td><strong>filter</strong></td><td>Filter data from API</td><td>*List</td></tr><tr><td><strong>filter-op</strong></td><td>Filter operators for filtering data</td><td>*.List</td></tr><tr><td><strong>first</strong></td><td>Number of entities to return from beginning of the result set. Max: 100. Default: 30</td><td>*.List</td></tr><tr><td><strong>include_deleted</strong></td><td>Returns deleted data<br>Default: False</td><td>*.Get, *.List</td></tr><tr><td><strong>last</strong></td><td>Return only the "last" number of entities from result set. When used with first parameter, then it returns last M records from the first N records.</td><td>*.List</td></tr><tr><td><strong>load-only</strong></td><td>Loads only api_fields defined within this parameter. You can use multiple values separated via ',' colon. If not used, then all fields are returned. You can use dots '.' to specify load only fields in nested as well.<br>Example: <code>load-only=id,name,owner.id</code></td><td>*.List</td></tr><tr><td><strong>order-by</strong></td><td>Order by values. Use api_name of field to sort by ascending. Prefix api_name with '-' to descending sort. You can use multiple values separated via ',' colon<br>Example: <code>order-by=created,-modified</code></td><td>*.List</td></tr><tr><td><strong>rollback-method</strong></td><td><p>Used in bulk updates/create, to rollback data that failed. <br>0 - rollback all, 1 - rollback only failed records.</p><p>Default:0<br><a href="/pages/e7vJwDDcUNf7j6hmm1YA"><strong>See Bulk Update and Create</strong></a></p></td><td>*.batchmethods</td></tr></tbody></table>

#### Validation

Query parameter: ***validation-level***

Helps when a developer doesn´t want to create data inside Coevera valid for some reason.&#x20;

When the business has many required fields on the Entities, you might want to skip the validation of those fields and populate only fields that you actually need.

| Option     | Description                                                                                                                                                             |
| ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 0(default) | <p>Validate each field on the entity.<br>Without even specifying this parameter, this is the general behavior of API - all API requests are automatically validated</p> |
| 2          | Validate only changed fields in the actual request                                                                                                                      |
| 4          | <p>Validate only system fields<br>Custom/User-defined fields are not validated. Read about <a href="/pages/gSiY1dt9oMGbLfq0ubub">fields</a></p>                         |
| 8          | Allows to override readonly fields                                                                                                                                      |
| 16         | <p>Allows setting entity on the deleted relationship.<br>Example: user, an account might be deleted</p>                                                                 |

**Example of Request**

Using validation as query parameter. In this case example, the validation is skipped for options "4" and "16"

```
{{baseUrl}}/entities/Opportunities?validation-level=416
```

#### Example of invalid Data in Application

The Majority of Invalid entities in the application look normal, however, after updating the data the user will see the information about invalid data

![(Before user update )This record skipped validation and it was created through API without required field "Primary Account name" ](/files/HCTsPYnAaFoAx1pntVhB)

![(After Update) User cannot save the record, because it is required. He needs to select Primary Account name](/files/4uKGSW4vqyiUldmYAflF)

#### Expand

Expand related entity. Use api\_names of related fields. You can use multiple values separated via ',' comma. If not used, the URI link will be returned instead. You can use '.' to expand nested entities as well.

Example: `expand=owner,sales_unit,account_relations.account`

```
{{baseUrl}}/entities/Pipelines?expand=steps
```

Expand parameter can be used also in case of custom lookup fields.

```
{{baseUrl}}/entities/Accounts?expand=cf_lookup_account_contact.object
```

#### Filter, Filter-op

**Filter**

Use the API name of the field in braces to filter by this field. To do the advanced filter, use with combination with filter-op parameter.

Example: `filter[api-field-name]=Example`

```
{{baseUrl}}/entities/Pipelines?expand=steps&filter[name]=Test Pipeline
```

**Filter-op**

Filter-op stands for filter operator. Below is the list of operators. You can combine several operators with `filter[api-field-name]` parameter

```
eq - equals
ieq - case insensitive equals, e.g. "example" will match "Example" as well as "eXAmple"
contains - partial match, e.g. "xampl" will match "example"
starts - matches which starts with string, e.g. "exam" will match "example"
ends - matches which ends with string, e.g. "ample" will match "example"
icontains - same as contains, but case insensitive
istarts - same as starts, but case insensitive
iends - same as end, but case insensitive
null - lookup for null values
empty - lookup for empty values (e.g. string == "", or "  ")
gt - greater than
gte - greater or equal than
lt - less than
lte - less or equal than
```

```
{{baseUrl}}/entities/Pipelines?expand=steps&filter-op[name]=contains&filter[name]=Test Pipeline&filter-op[id]=eq&filter[id]=90be8a83-bae8-401d-9e5e-c4564a986270
```

<br>


# Dates

### Dates in Coevera

All dates are stored in the **UTC** timezone. Data are formatted by standard `ISO 8601`

Example of Date value: `2019-02-01 07:41:49.529970+00:00`

{% hint style="info" %}
If you include Timezone in the request header, Coevera will automatically convert dates to the specified timezone. For Timezones Coevera uses a uniform [**naming convention**](https://en.wikipedia.org/wiki/Tz_database).&#x20;

Header Example: **Timezone: America/Chicago**&#x20;
{% endhint %}

### Dates sent to Coevera

Dates sent to Coevera should be converted into the UTC timezone.


# Pagination

Coevera sends a maximum of **100** (Default: **30**) records per request. The limit can be changed by [**API parameter** ](/api-docs/core-api-concepts/api-parameters)`first`

Pagination is available after the successful call of all `.list` Endpoints. Then API returns the following data

```json
{
	"success": true,
	"total": 107,
	"page_info": {
		"start_cursor": "WyIwMzU4NmNhMS1mMmJjLTQ2MDctYWE3Ni1jYWYyYTNlOWQ5ODciXQ==",
		"end_cursor": "WyI0MGUxMGE1MC00ZTYxLTQ0M2YtYmUzOC0xNmNjMzQ5NTM2NGUiXQ==",
		"has_previous_page": false,
		"has_next_page": true
	},
	"data": [...]
}
```

#### Using Cursor for pagination

To retrieve all data, it is recommended to use `end_cursor` with combination of [**API Parameter**](/api-docs/core-api-concepts/api-parameters) `after.` Iterate through the list, until the `has_next_page` is `false`

```
{{baseUrl}}/entities/Opportunities?after=WyI0MGUxMGE1MC00ZTYxLTQ0M2YtYmUzOC0xNmNjMzQ5NTM2NGUiXQ==
```

**Pagination done programmatically**

```python
while has_next_page, do get_records(after=end_cursor)
```


# Bulk Create, Update, Delete

It is recommended to use Bulk Create, Update, Delete methods when working with a lot of data at once.

| Operation Name | Endpoint        |
| -------------- | --------------- |
| Create, Update | .\*batch-modify |
| Delete         | \*.batch-delete |

### Bulk Create, Update

Coevera API supports creating, updating records in one `*.batch-modify`request

1. When the `ID` is specified in an object, it works as **an update method**
2. When the `ID` is not specified in an object, it works as **a create method**

**Snippet**

```
POST /entities/{{Entity-name}}/batch-modify
[
    {"id": "123", "name": "update"}, 
    {"name": "create"}
]
```

### Using Rollback for Bulk operations

Rollback is [API parameter](/api-docs/core-api-concepts/api-parameters)**,** that can help you to rollback data that has failed for some reason (eg. data became invalid).

**Example**

In this example, we are going to bulk update Accounts, with the rollback method turned on.

**Rollback = 0**

If at least one object in a request is invalid, any operation isn´t executed (all data are rollbacked)

```
POST {{baseUrl}}/entities/Accounts/batch-modify?rollback-method=0
[
    {
        "id": "0bc376a4-c579-413a-9221-e86e4a134766",
        "name": "Account - Updated"
    },
    {
        "name": "Account - Created"
    }
]
```

```json
{
    "code": 40000,
    "name": "ERROR_ENTITY_VALIDATION",
    "message": "\n[owner_id] Relation Account.owner_id=00000000-0000-0000-0000-000000011a3d to Client doesn't exist!",
    "entity_id": "0bc376a4-c579-413a-9221-e86e4a134766",
    "entity_name": "Account",
    "entity_errors": [],
    "field_errors": [
        {
            "field_id": "5b67c561-0136-0c86-9dc0-0b4c9acb42f5",
            "field_name": "owner_id",
            "name": "ERROR_FIELD_VALIDATION",
            "code": 40002,
            "errors": [
                {
                    "code": 120,
                    "name": "ERROR_RELATIONS_DOESNT_EXIST",
                    "message": "[owner_id] Relation Account.owner_id=00000000-0000-0000-0000-000000011a3d to Client doesn't exist!",
                    "field_id": "5b67c561-0136-0c86-9dc0-0b4c9acb42f5",
                    "field_name": "owner_id"
                }
            ]
        }
    ],
    "step_checklist_errors": [],
    "entity_index": null,
    "http_status": 422,
    "success": false
}
```

**Rollback=1**

If an object in a request is invalid, it is not saved but other valid records are saved successfully. If the error occurs it is then returned in a response

```
POST {{baseUrl}}/entities/Accounts/batch-modify?rollback-method=1
[
    {
        "id": "0bc376a4-c579-413a-9221-e86e4a134766",
        "name": "Account - Updated"
    },
    {
        "name": "Account - Created",
        "owner_id": "00000000-0000-0000-0000-000000011a7d"
    }
]
```

```json
{
    "success": false,
    "data": [
        {
            "code": 40000,
            "name": "ERROR_ENTITY_VALIDATION",
            "message": "\n[owner_id] Relation Account.owner_id=00000000-0000-0000-0000-000000011a3d to Client doesn't exist!"
        },
        "f75fc63f-8c6f-499e-b9d2-ff16bcefdd83"
    ]
}
```


# Webhooks(Real-time updates)

**Webhooks** allow you to receive programmatic notifications from Coevera about changes to your data as they happen in real time.&#x20;

Rather than querying you to pull information via the API, webhooks will **push** information to your endpoint when the event happens.&#x20;

**Example:** When the webhook is registered on Account Creation, then when the Account is created Coevera sends to your specified URL the JSON with the body of the newly created Account.&#x20;

## Registering Webhooks&#x20;

Registering webhook means, that you are going to set a listener on an event if something happens. Take a look at the table below which events are supported

<table><thead><tr><th width="166.57734763345138">Entity Name</th><th>Event Name</th></tr></thead><tbody><tr><td>Account</td><td><p><strong>Account.*</strong></p><p><strong>Account.Create</strong><br><strong>Account.Update</strong><br><strong>Account.Delete</strong><br><strong>Account.DocumentLinked</strong><br><strong>Account.OwnerChanged</strong></p></td></tr><tr><td>Contact</td><td><p><strong>Contact.*</strong></p><p><strong>Contact.Create</strong><br><strong>Contact.Update</strong><br><strong>Contact.Delete</strong><br><strong>Contact.DocumentLinked</strong><br><strong>Contact.OwnerChanged</strong></p></td></tr><tr><td>Opportunity</td><td><strong>Opportunity.*</strong><br><strong>Opportunity.Create</strong><br><strong>Opportunity.Update</strong><br><strong>Opportunity.Delete</strong><br><strong>Opportunity.DocumentLinked</strong><br><strong>Opportunity.OwnerChanged</strong><br><strong>Opportunity.Move</strong> (when the sales step is changed)<br><strong>Opportunity.Lost</strong> (when the Opportunity is Archived/LOst)<br><strong>Opportunity.Won</strong> (when the opportunity was won)<br><strong>Opportunity.Qualify</strong> (when the opportunity was created from Lead - Qualified)</td></tr><tr><td>Lead</td><td><p><strong>Lead.*</strong><br><strong>Lead.Create</strong><br><strong>Lead.Update</strong><br><strong>Lead.Delete</strong><br><strong>Lead.DocumentLinked</strong><br><strong>Lead.OwnerChanged</strong></p><p><strong>Lead.Lost</strong> (when the lead was Archived/Lost)<br><strong>Lead.BackToLead</strong> (when the opportunity was reverted to Lead)</p></td></tr><tr><td>Task</td><td><strong>Task.*</strong><br><strong>Task.Create</strong><br><strong>Task.Update</strong><br><strong>Task.Delete</strong><br><strong>Task.DocumentLinked</strong><br><strong>Task.OwnerChanged</strong><br><strong>Task.Comment</strong></td></tr><tr><td>Email</td><td><strong>Email.*</strong><br><strong>Email.Create</strong><br><strong>Email.Update</strong><br><strong>Email.Delete</strong><br><strong>Email.DocumentLinked</strong></td></tr><tr><td>Appointment</td><td><strong>Appointment.*</strong><br><strong>Appointment.Create</strong><br><strong>Appointment.Update</strong><br><strong>Appointment.Delete</strong><br><strong>Appointment.DocumentLinked</strong><br><strong>Appointment.OwnerChanged</strong><br><strong>Appointment.Comment</strong></td></tr><tr><td>Product</td><td><p><strong>Product.*</strong></p><p><strong>Product.Create</strong></p><p><strong>Product.Update</strong></p><p><strong>Product.Delete</strong></p></td></tr><tr><td>Product Line Items (OpptyProductRelation)</td><td><strong>OpptyProductRelation.*</strong><br><strong>OpptyProductRelation.Create</strong><br><strong>OpptyProductRelation.Update</strong><br><strong>OpptyProductRelation.Delete</strong></td></tr><tr><td>Custom Entity (Records)</td><td><p><strong>CustomEntity.*</strong></p><p><strong>CustomEntity.Create</strong></p><p><strong>CustomEntity.Update</strong></p><p><strong>CustomEntity.Delete</strong></p><p><strong>CustomEntity.DocumentLinked</strong></p><p><strong>CustomEntity.OwnerChanged</strong></p></td></tr></tbody></table>

### Register the Webhook

Register a webhook by calling this Endpoint

{% openapi src="/files/483oBiKgEGR3bPMLT8VK" path="/entities/Webhooks" method="post" %}
[openapi (1).json](https://3470708952-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFpjbhrh1xo0SPAbAc7Ny%2Fuploads%2FOlNVdYj1h5GSxQmLHAjz%2Fopenapi%20\(1\).json?alt=media\&token=4be07353-5170-4a95-9100-4f16545d47b0)
{% endopenapi %}

#### Required Fields

<table><thead><tr><th width="239.74159671426082">Required API field Name</th><th>Description</th></tr></thead><tbody><tr><td>insecure_ssl</td><td>false (Recommended)<br>If True, remote side ssl certificate will not be validated when delivering notifications.</td></tr><tr><td>events</td><td>See table above to see what events you can use</td></tr><tr><td>url</td><td>The Server URL where the Webhook body should be sent</td></tr><tr><td>options</td><td>Options are described below</td></tr></tbody></table>

**Webhook options**

<table><thead><tr><th>Option Name</th><th width="150">REST API format</th><th>Description</th></tr></thead><tbody><tr><td><strong>On Field change</strong></td><td>on-field-change</td><td>Use when you want to trigger a webhook only on specific fields changes (eg. Opportunity value was changed)</td></tr><tr><td><strong>Skipping webhooks</strong></td><td>skip_keys</td><td>You can specify list of strings under "skip_keys" key in options. Whenever you make an API request with header "Webhook-Skip-Key" equal to any of the specified skip keys, the Webhook will not be triggered. This can prevent a Webhook loop.<br><br><strong>Example:</strong> Insert into every header of your Post Request the information "my integration", so Pipeliner is not sending the webhooks back whenever the record is created/updated and the record was created by request with header "my integration"</td></tr><tr><td><strong>Expanding data of Linked entities</strong></td><td>related_entity</td><td>When you want to get data about related Entity.<br><br><strong>Example:</strong> You have webhook on Opportunity. When you receive data on the Opportunity, you would like to know information about all Product Line items on the Opportunity</td></tr><tr><td><strong>Api paremeters</strong></td><td>expand, load_only, filter, filter-op</td><td>You can use some of the <a href="/pages/P3qrQcI4CkQnV73Q3P71"><strong>API parameters</strong></a> to work with webhooks<br><br><strong>Example:</strong> You want to trigger Webhook only on Open Opportunities</td></tr><tr><td><strong>Webhook for Custom entity</strong></td><td>custom_entity_api_name</td><td>Use when you want to trigger Webhook on Custom entities. You have to add API names of required custom entities.</td></tr><tr><td><strong>Webhook throttling</strong></td><td>chunk_size</td><td><p>Default:100</p><p>Defines how much data should come in one request</p></td></tr><tr><td><strong>Webhook throttling delay</strong></td><td>chunk_delay</td><td><p>Default:0 </p><p>each chunk will be delayed by N * chunk_delay seconds, where N is index of chunk</p></td></tr></tbody></table>

**Example of Option parameters**

```json
{
    "custom_entity_api_name": [ "CE_Bid", "CE_Campaign" ],	
    "entity": {
        "Contact": {
            "expand": [
                "primary_account",
                "primary_contact",
                "task_relations.task"
            ],
            "load-only": [
                "id",
                "primary_account",
                "primary_contact.first_name",
                "task_relations.task"
            ],
            "filter": {
                "email1": [
                    "test@example.com",
                    "test@example.net"
                ],
                "email2": "test@example.com"
            },
            "filter-op": {
                "email1": "eq"
            }, 
            "on-field-change": [
                "email1"
            ]
        },
        "Account": {
            "filter": {
                "owner_id": [
                    "9900cce6-bcd6-412a-bcd1-1904556c949a"
                ]
            }
        }
    },
    "related_entity": {
        "expand": [
            "contact"
        ],
        "load-only": [
            "id",
            "contact"
        ]
    },
    "skip_keys": [
        "gmail_sync",
        "custom_integration"
    ]
}
```

### **Webhooks examples**

For testing our examples we are going to create a request bin when we will sent our webhooks. We are going to use this service <https://requestbin.com/>.&#x20;

#### **Trigger webhook when Account is created**

```json
POST 
{{baseUrl}}/entities/Webhooks
{
    "insecure_ssl": false,
    "url": "https://enrdznpu5i7jp.x.pipedream.net",
    "events": [
        "Account.Create"
    ],
    "options": {}
}
```

Once the webhook was registered go to the Application and create a new account. Then check the body of created Account in requestbin application.

#### **Trigger webhook on field change**

When the Opportunity fields `Opportunity value` or `closing_date` are updated on the Opportunity send notification

```json
POST 
{{baseUrl}}/entities/Webhooks
{
    "insecure_ssl": false,
    "url": "https://enrdznpu5i7jp.x.pipedream.net",
    "events": [
        "Opportunity.Update"
    ],
    "options": {
        "entity": {
            "Opportunity": {
                "on-field-change": ["closing_date", "value"]
            }
        }
    }
}
```

**Trigger webhook on filtered data**

Listen to notifications only when the Opportunity is Opened (not won or lost). When attribute `filter-op` is not defined Pipeliner automatically uses "eq" value to filter the results

```json
{
    "insecure_ssl": false,
    "url": "https://enrdznpu5i7jp.x.pipedream.net",
    "events": [
        "Opportunity.Update"
    ],
    "options": {
        "entity": {
            "Opportunity": {
                "filter":{
                    "status": "Open"
                }
            }
        }
    }
}
```

**Webhooks for Custom Entity records**

To use webhooks for custom entity, the attribute `custom_entity_api_name` should contain API names of required custom entities.

```json
{
    "insecure_ssl": false,
    "url": "https://enrdznpu5i7jp.x.pipedream.net",
    "events": [
        "CustomEntity.Create", 
	"CustomEntity.Update"
    ],
    "options": {
        "custom_entity_api_name": [ "CE_Bid", "CE_Campaign" ],
        "entity": {
            "CE_Bid": {
		"filter": {
		    "name": "important"
		},
		"filter-op": {
		    "name": "contains"
		}
	    }
        }
    }
}
```


# Create Account

This tutorial should help you create the first Account. Before moving forward, make sure your [**Authentication** ](/api-docs/overview/authentication)works and you understand the [**Key Concepts**](/api-docs/core-api-concepts/understanding-the-crm-concept) of the Coevera API, and make sure you know how to use [**API parameters**](/api-docs/core-api-concepts/api-parameters)

**The Account** represents the Company/organization, that your company is dealing with. Go to the web Application and Accounts can be located on the Accounts screen.&#x20;

![](/files/osl21dVr6A1Sxh7geIaR)

## Tutorial Assignment <a href="#tutorial-assignment" id="tutorial-assignment"></a>

Create an Account in Coevera with Several Contacts (with bulk create method). For this account, we will set the `industry` field to *`Agriculture`*

### 0. Required fields <a href="#id-0.-required-fields" id="id-0.-required-fields"></a>

<table><thead><tr><th width="251.76811427063683">Required API field Name</th><th>Description</th></tr></thead><tbody><tr><td>name</td><td>Name of the Account</td></tr><tr><td>owner_id</td><td>Id of the User in Coevera Application</td></tr></tbody></table>

### 1.  Prepare Data

#### Owner\_id

Load an id of the user with the [default sales unit](/api-docs/core-api-concepts/understanding-the-crm-concept#users-and-roles-and-sales-units-accessing-records). This user will become the owner of the newly created Account.

{% openapi src="/files/483oBiKgEGR3bPMLT8VK" path="/entities/Clients" method="get" %}
[openapi (1).json](https://3470708952-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFpjbhrh1xo0SPAbAc7Ny%2Fuploads%2FOlNVdYj1h5GSxQmLHAjz%2Fopenapi%20\(1\).json?alt=media\&token=4be07353-5170-4a95-9100-4f16545d47b0)
{% endopenapi %}

```
{{baseUrl}}/entities/Clients?load-only=id,default_unit_id&filter[email]=john.doe@example.com
```

```json
{
            "id": "00000000-0000-0000-0000-000000011a7d",
            "default_unit_id": "aba4a358-f3f8-4f55-b3ed-dd5cf589103b"
}
```

{% hint style="info" %}
We don´t necessarily need to load the default unit id. If only owner\_id is specified in the final request, Coevera will automatically create an Account with the default User´s sales unit. (See step 2. of this tutorial)
{% endhint %}

#### Industry

We need to retrieve existing values of Industry field. For more information how to work with fields and get values read [Fields section](/api-docs/core-api-concepts/fields).

```
GET 
{{baseUrl}}/entities/Fields?expand=data_set&load-only=api_name,data_set.option_name,data_set.id&filter[api_name]=industry_id
```

```
"data": [
        {
           "api_name": "industry_id",
           "data_set": [
                {
                    "id": "36430b74-f0ae-01b0-bc4a-47d6235f9405",
                    "option_name": "Accounting"
                },
                {
                    "id": "3e046e52-00e4-097b-b2a4-b58af0381541",
                    "option_name": "Agriculture"
                },
                {
                    "id": "acbda72f-2054-0b71-9d42-cb35aaa37600",
                    "option_name": "Broadcasting"
                },
                ...
    }
 ]       
                
                
```

### 2.  Create Account

Let´s Take data from Step 1. and use them in the following request to create a Contact.

{% openapi src="/files/483oBiKgEGR3bPMLT8VK" path="/entities/Accounts" method="post" %}
[openapi (1).json](https://3470708952-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFpjbhrh1xo0SPAbAc7Ny%2Fuploads%2FOlNVdYj1h5GSxQmLHAjz%2Fopenapi%20\(1\).json?alt=media\&token=4be07353-5170-4a95-9100-4f16545d47b0)
{% endopenapi %}

```json
{
    "name": "My New Account",
    "owner_id": "00000000-0000-0000-0000-000000011a7d",
    "industry_id": "3e046e52-00e4-097b-b2a4-b58af0381541"
}
```

{% hint style="info" %}
When working with Dropdown fields like `industry_id` you need to use a relation to the id of the value in field data\_set. In our case Option **Agriculture** has id 3e046e52-00e4-097b-b2a4-b58af0381541
{% endhint %}


# Create Contact

This tutorial should help you create the first Contact. Before moving forward, make sure your [**Authentication** ](/api-docs/overview/authentication)works and you understand the [**Key Concepts**](/api-docs/core-api-concepts/understanding-the-crm-concept) of the Coevera API ,and make sure you know how to use [**API parameters**](/api-docs/core-api-concepts/api-parameters)

**The Contact** represents existing contact from the company, that your company is dealing with. Go to the web Application and Contacts can be located on the Contacts screen. Contact should not be standalone records, but they should always be linked to the Accounts.

![](/files/swVjgdqz6BFX1o1sf4VT)

## Tutorial Assignment

Create a Contact in Coevera with Job Position/Job Title. This contact will be linked with one Account.

### 0.  Required fields

<table><thead><tr><th width="251.76811427063683">Required API field Name</th><th>Description</th></tr></thead><tbody><tr><td>first_name <em>or</em> last<em>_</em>name</td><td><p>Name of the Contact. Name of the Contact is created as "Fist_<em>name" + "Middle_Name" + "Last</em>_Name"<br></p><p>Required: at least one of the first_name, last<em>_</em>name</p></td></tr><tr><td>owner_id</td><td>Id of the User in Coevera Application</td></tr></tbody></table>

### 1.  Prepare Data

#### Owner\_id

Load an id of the user with the [default sales unit](/api-docs/core-api-concepts/understanding-the-crm-concept#users-and-roles-and-sales-units-accessing-records). This user will become the owner of the newly created Contact.

{% openapi src="/files/483oBiKgEGR3bPMLT8VK" path="/entities/Clients" method="get" %}
[openapi (1).json](https://3470708952-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFpjbhrh1xo0SPAbAc7Ny%2Fuploads%2FOlNVdYj1h5GSxQmLHAjz%2Fopenapi%20\(1\).json?alt=media\&token=4be07353-5170-4a95-9100-4f16545d47b0)
{% endopenapi %}

```
{{baseUrl}}/entities/Clients?load-only=id,default_unit_id&filter[email]=john.doe@example.com
```

```json
{
            "id": "00000000-0000-0000-0000-000000011a7d",
            "default_unit_id": "aba4a358-f3f8-4f55-b3ed-dd5cf589103b"
}
```

{% hint style="info" %}
We don´t necessarily need to load the default unit id. If only owner\_id is specified in the final request, Coevera will automatically create contact with the default User´s sales unit. (See step 2. of this tutorial)
{% endhint %}

#### Account\_id

We want to assign this contact with an Account. We are going to search for Accounts by email address. But you can use whatever parameter.

```
{{baseUrl}}/entities/Accounts?include-deleted=false&filter[email1]=info@ziemann-and-sons.de
```

```json
{
            "is_delete_protected": false,
            "id": "0bc376a4-c579-413a-9221-e86e4a134766",
            "is_deleted": false,
            "modified": "2019-02-01 10:01:23.011709+00:00",
            "created": "2019-01-30 11:44:23.586083+00:00",
            "account_type": "https://us-east.pipelinersales.com/api/v100/rest/spaces/nv3_PipelinerDev/entities/AccountTypes/a456236f-6f23-0908-abfd-384aa0f62f9e",
            "customer_type": "https://us-east.pipelinersales.com/api/v100/rest/spaces/nv3_PipelinerDev/entities/Data/04444b3a-c669-03bc-2c49-bcd7f047d41a",
            "industry": "https://us-east.pipelinersales.com/api/v100/rest/spaces/nv3_PipelinerDev/entities/Data/acbda72f-2054-0b71-9d42-cb35aaa37600",
            "owner": "https://us-east.pipelinersales.com/api/v100/rest/spaces/nv3_PipelinerDev/entities/Clients/00000000-0000-0000-0000-000000011a3d",
            "parent_account": null,
            "parent_account_relation_type": null,
            "picture": "https://us-east.pipelinersales.com/api/v100/rest/spaces/nv3_PipelinerDev/entities/CloudObjects/5ddfe953-a569-48e1-86bb-271e6506e7d0",
            "unit": "https://us-east.pipelinersales.com/api/v100/rest/spaces/nv3_PipelinerDev/entities/SalesUnits/ea33e8fb-9a56-4802-a175-2d1f406af7cf",
            "account_class": 5,
            "account_type_id": "a456236f-6f23-0908-abfd-384aa0f62f9e",
            "address": "7 Lillian Plaza",
            "city": "Coronda",
            "comments": "",
            "country": "Argentina",
            "customer_type_id": "04444b3a-c669-03bc-2c49-bcd7f047d41a",
            "email1": "info@ziemann-and-sons.de",
            "email2": "",
            "email3": "",
            "email4": "",
            "email5": "",
            "health_category": null,
            "health_status": null,
            "home_page": "www.ziemannandsons.com",
            "industry_id": "acbda72f-2054-0b71-9d42-cb35aaa37600",
            "name": "Ziemann and Sons",
            "owner_id": "00000000-0000-0000-0000-000000011a3d",
            "parent_account_id": null,
            "parent_account_relation_type_id": null,
            "phone1": "+1 (888) 500-8000",
            "..."
        }
```

### 2. Create Contact

Let´s Take data from Step 1. and use them in the following request to create a Contact.

{% openapi src="/files/483oBiKgEGR3bPMLT8VK" path="/entities/Contacts" method="post" %}
[openapi (1).json](https://3470708952-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFpjbhrh1xo0SPAbAc7Ny%2Fuploads%2FOlNVdYj1h5GSxQmLHAjz%2Fopenapi%20\(1\).json?alt=media\&token=4be07353-5170-4a95-9100-4f16545d47b0)
{% endopenapi %}

```json
{
    "first_name": "Pipeliner",
    "last_name":"Developer",
    "position": "This is position in Quick Account Position field",
    "owner_id": "00000000-0000-0000-0000-000000011a7d",
    "account_relations": [
        {
        "account_id": "0bc376a4-c579-413a-9221-e86e4a134766",
        "position": "This is Primary Account Job Title",
        "is_primary": true
        }
    ]
}
```

**Linking Contact to Account**

To Link Contact with Account, we are going to create relation by creating new primary relation in `account_relations` array

**Setting up the Position**

`position` - In Pipeliner Application this api\_field is called `Quick Account Position`. This is the Contact field. Use this field when you are not linking Contact with Account immediately.

`account_position` - This is Primary Account Job Title. This position is linked directly with the Account. It is recommended to use this api\_field, as Contacts might have different positions on different Accounts.

![List view of Contacts](/files/NgZ4cKZMIPkzSNxWapQG)

![Detail of the Contact with Linked Account](/files/yNwGyPdSwKohV1w6rlz5)

**Possible Errors**

| Error description                                                              | Resolution                                                                                                                                                                                                             |
| ------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Error on field account\_relations. Exactly one 'is\_primary' item must be set. | <p>Use is\_primary flag for Account relation object. </p><p>-When creating account relations at least one Account needs to be primary<br>-When creating contact relations at least one Contact needs to be primary</p> |


# Create Opportunity

This tutorial should help you create the first Opportunity. Before moving forward, make sure your [**Authentication** ](/api-docs/overview/authentication)works and you understand the [**Key Concepts**](/api-docs/core-api-concepts/understanding-the-crm-concept) of the Coevera API and make sure you know how to use [**API parameters**](/api-docs/core-api-concepts/api-parameters)

**The Opportunity** represents existing potential business for a company. Go to the web Application and Opportunities can be located on the Opportunities screen. Opportunity is always part of the Coevera and pipeline step.

![](/files/XlHV07FRX5Fq7dIXvGwC)

{% hint style="info" %}
**The Pipeline** is the list of steps (eg. First Contact, Proposal, Closed/Won), that represents the life cycle of the opportunity. Set up your first [**Pipeline**](https://help.pipelinersales.com/en/articles/2724115-managing-your-first-pipeline)
{% endhint %}

## Tutorial Assignment

Create Opportunity in the Pipeline within the First Step of the Pipeline. This Opportunity will be Linked with an Account(Company) and multiple Contact that belongs to this Account.

### 0.  Required fields

<table><thead><tr><th width="308.2672043757614">Required API field Name</th><th>Description</th></tr></thead><tbody><tr><td>name</td><td>Name of the opportunity</td></tr><tr><td>owner_id</td><td>Id of the User in Coevera Application</td></tr><tr><td>closing_date</td><td>Expected Closing date. When the opportunity should be closed</td></tr><tr><td>step_id</td><td>ID of the Pipeline step where the Opportunity should be created</td></tr><tr><td>value</td><td>The business value of Opportunity, eg. dollar amount.<br><code>base_value -</code> The Real Business Value in dollars<br><code>currency_id -</code> The ID of currency saved in Coevera<br><code>value_foreign -</code> The value for currency_id (Use only with multicurrency setup)</td></tr></tbody></table>

### 1.  Prepare Data

#### Owner\_id

Load an id of the user with the [default sales unit](/api-docs/core-api-concepts/understanding-the-crm-concept#users-and-roles-and-sales-units-accessing-records). This user will become the owner of the newly created Opportunity.

{% openapi src="/files/483oBiKgEGR3bPMLT8VK" path="/entities/Clients" method="get" %}
[openapi (1).json](https://3470708952-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFpjbhrh1xo0SPAbAc7Ny%2Fuploads%2FOlNVdYj1h5GSxQmLHAjz%2Fopenapi%20\(1\).json?alt=media\&token=4be07353-5170-4a95-9100-4f16545d47b0)
{% endopenapi %}

```
{{baseUrl}}/entities/Clients?load-only=id,default_unit_id&filter[email]=john.doe@example.com
```

```json
{
            "id": "00000000-0000-0000-0000-000000011a7d",
            "default_unit_id": "aba4a358-f3f8-4f55-b3ed-dd5cf589103b"
}
```

{% hint style="info" %}
We don´t necessarily need to load the default unit id. If only owner\_id is specified in the final request, Coevera will automatically create the opportunity with the default User´s sales unit.  (See step 2. of this tutorial)
{% endhint %}

#### Step\_id

Pull Opportunity Pipelines and their steps. Store the ID of the First Step

{% openapi src="/files/483oBiKgEGR3bPMLT8VK" path="/entities/Pipelines" method="get" %}
[openapi (1).json](https://3470708952-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFpjbhrh1xo0SPAbAc7Ny%2Fuploads%2FOlNVdYj1h5GSxQmLHAjz%2Fopenapi%20\(1\).json?alt=media\&token=4be07353-5170-4a95-9100-4f16545d47b0)
{% endopenapi %}

```
{{baseUrl}}/entities/Pipelines?expand=steps&filter-op[name]=contains&filter[name]=Test Pipeline
```

```json
 {
            "is_delete_protected": false,
            "id": "90be8a83-bae8-401d-9e5e-c4564a986270",
            "is_deleted": false,
            "modified": "2020-09-25 10:48:29.825069+00:00",
            "created": "2020-08-12 15:00:21.732550+00:00",
            "color": 16233984,
            "name": "Test Pipeline",
            "revision": 66001,
            "steps": [
                {
                    "is_delete_protected": false,
                    "id": "de115511-5dc1-46c3-86d9-f714457208dd",
                    "is_deleted": false,
                    "modified": "2020-08-12 15:00:21.734413+00:00",
                    "created": "2020-08-12 15:00:21.734454+00:00",
                    "pipeline": "https://us-east.pipelinersales.com/api/v100/rest/spaces/nv3_PipelinerDev/entities/Pipelines/90be8a83-bae8-401d-9e5e-c4564a986270",
                    "name": "First",
                    "percent": 15,
                    "pipeline_id": "90be8a83-bae8-401d-9e5e-c4564a986270",
                    "sort_order": 0,
                    "timeframe": null,
                    "revision": 65654,
                    "documents": [],
                    "step_checklists": []
                }
                
}
```

#### Account\_id

We are going to search for Accounts by email address. But you can use whatever parameter.

```
{{baseUrl}}/entities/Accounts?include-deleted=false&filter[email1]=info@ziemann-and-sons.de
```

```json
{
            "is_delete_protected": false,
            "id": "0bc376a4-c579-413a-9221-e86e4a134766",
            "is_deleted": false,
            "modified": "2019-02-01 10:01:23.011709+00:00",
            "created": "2019-01-30 11:44:23.586083+00:00",
            "account_type": "https://us-east.pipelinersales.com/api/v100/rest/spaces/nv3_PipelinerDev/entities/AccountTypes/a456236f-6f23-0908-abfd-384aa0f62f9e",
            "customer_type": "https://us-east.pipelinersales.com/api/v100/rest/spaces/nv3_PipelinerDev/entities/Data/04444b3a-c669-03bc-2c49-bcd7f047d41a",
            "industry": "https://us-east.pipelinersales.com/api/v100/rest/spaces/nv3_PipelinerDev/entities/Data/acbda72f-2054-0b71-9d42-cb35aaa37600",
            "owner": "https://us-east.pipelinersales.com/api/v100/rest/spaces/nv3_PipelinerDev/entities/Clients/00000000-0000-0000-0000-000000011a3d",
            "parent_account": null,
            "parent_account_relation_type": null,
            "picture": "https://us-east.pipelinersales.com/api/v100/rest/spaces/nv3_PipelinerDev/entities/CloudObjects/5ddfe953-a569-48e1-86bb-271e6506e7d0",
            "unit": "https://us-east.pipelinersales.com/api/v100/rest/spaces/nv3_PipelinerDev/entities/SalesUnits/ea33e8fb-9a56-4802-a175-2d1f406af7cf",
            "account_class": 5,
            "account_type_id": "a456236f-6f23-0908-abfd-384aa0f62f9e",
            "address": "7 Lillian Plaza",
            "city": "Coronda",
            "comments": "",
            "country": "Argentina",
            "customer_type_id": "04444b3a-c669-03bc-2c49-bcd7f047d41a",
            "email1": "info@ziemann-and-sons.de",
            "email2": "",
            "email3": "",
            "email4": "",
            "email5": "",
            "health_category": null,
            "health_status": null,
            "home_page": "www.ziemannandsons.com",
            "industry_id": "acbda72f-2054-0b71-9d42-cb35aaa37600",
            "name": "Ziemann and Sons",
            "owner_id": "00000000-0000-0000-0000-000000011a3d",
            "parent_account_id": null,
            "parent_account_relation_type_id": null,
            "phone1": "+1 (888) 500-8000",
            "..."
        }
```

#### Contact\_id

We are going to search for Contacts that are linked to the Account. We are going to use `Account_id` from the previous Step *and list all* `contact_id` *that exists on the Account*

{% openapi src="/files/483oBiKgEGR3bPMLT8VK" path="/entities/ContactAccountRelations" method="get" %}
[openapi (1).json](https://3470708952-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFpjbhrh1xo0SPAbAc7Ny%2Fuploads%2FOlNVdYj1h5GSxQmLHAjz%2Fopenapi%20\(1\).json?alt=media\&token=4be07353-5170-4a95-9100-4f16545d47b0)
{% endopenapi %}

```
{{baseUrl}}/entities/ContactAccountRelations?filter[account_id]=0bc376a4-c579-413a-9221-e86e4a134766
```

```json
{
            "is_delete_protected": false,
            "id": "7bb50668-badb-4c4b-a184-2f2be3df4fd8",
            "is_deleted": false,
            "modified": "2019-01-30 11:54:15.289916+00:00",
            "created": "2019-01-30 11:54:15.289965+00:00",
            "account": "https://us-east.pipelinersales.com/api/v100/rest/spaces/nv3_PipelinerDev/entities/Accounts/0bc376a4-c579-413a-9221-e86e4a134766",
            "contact": "https://us-east.pipelinersales.com/api/v100/rest/spaces/nv3_PipelinerDev/entities/Contacts/02bdc9f6-4dfb-479e-84ba-f6c3b96c39ba",
            "account_id": "0bc376a4-c579-413a-9221-e86e4a134766",
            "comment": "",
            "contact_id": "02bdc9f6-4dfb-479e-84ba-f6c3b96c39ba",
            "is_assistant": false,
            "is_primary": true,
            "is_sibling": false,
            "position": "",
            "relationship": 0,
            "revision": 184,
            "account_roles": []
        }
```

#### Value

![](/files/gi6FDG6ALfyenXbpXyX1)

1. **Foreign value (required/optional)** - This is the value that the User (SalesPerson) can put into the system. This value is depending on currency\_id.
   1. &#x20;Example: if your salespeople want to have an Opportunity Value in Euro, for currency\_id use Euro, into the Foreign value put the amount in Euro
2. **currency\_id** **(Required)** - the currency for the opportunity (like dollar, euro, etc.). In Pipeliner there are two types of currencies
   1. [Base currency](https://help.pipelinersales.com/en/articles/2710228-base-currency) - System currency (the main currency)
   2. [Multiple currencies](https://help.pipelinersales.com/en/articles/2713635-currencies) (custom currencies) - When your business works with multiple currencies
3. &#x20;**base\_value (required/optional)** - this value is always calculated according to the Base Currency

{% hint style="info" %}
You can use one of the foreign values, base\_value. It depends on what fits you better.

\
When you define base value, then Foreign Currency is calculated automatically based on [Exchange rates](https://help.pipelinersales.com/en/articles/2713643-exchange-rates)

When you define Foreign Currency, then the base value is calculated automatically based on Exchange rates
{% endhint %}

#### Value.currency\_id

In this tutorial, we don´t use a multi-currency setup, so we are going to search for the base currency (system currency). To retrieve base currency let´s use the following request. Base currency is flagged as `is_base:true`

{% openapi src="/files/483oBiKgEGR3bPMLT8VK" path="/entities/Currencies" method="get" %}
[openapi (1).json](https://3470708952-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFpjbhrh1xo0SPAbAc7Ny%2Fuploads%2FOlNVdYj1h5GSxQmLHAjz%2Fopenapi%20\(1\).json?alt=media\&token=4be07353-5170-4a95-9100-4f16545d47b0)
{% endopenapi %}

```
{{baseUrl}}/entities/Currencies?filter[is_base]=true
```

```json
{
            "is_delete_protected": true,
            "id": "c4ca4238-a0b9-0382-0dcc-509a6f75849b",
            "is_deleted": false,
            "modified": "2019-01-30 11:20:40.481012+00:00",
            "created": "2019-01-11 13:47:33.247720+00:00",
            "code": "USD",
            "is_base": true,
            "symbol": "$",
            "revision": 18,
            "currency_exchange_rates": []
}
```

### 2. Create Opportunity

Let´s Take data from Step 1. and use them in the following request to create an Opportunity.

{% openapi src="/files/483oBiKgEGR3bPMLT8VK" path="/entities/Opportunities" method="post" %}
[openapi (1).json](https://3470708952-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFpjbhrh1xo0SPAbAc7Ny%2Fuploads%2FOlNVdYj1h5GSxQmLHAjz%2Fopenapi%20\(1\).json?alt=media\&token=4be07353-5170-4a95-9100-4f16545d47b0)
{% endopenapi %}

```json
{
    "closing_date": "2019-01-01",
    "name": "New Opportunity",
    "owner_id": "00000000-0000-0000-0000-000000011a7d",
    "step_id": "de115511-5dc1-46c3-86d9-f714457208dd",
    "value": {
        "base_value": 100,
        "currency_id": "c4ca4238-a0b9-0382-0dcc-509a6f75849b"
    },
    "account_relations": [
       {
           "account_id": "0bc376a4-c579-413a-9221-e86e4a134766",
           "is_primary": true
           
       }
    ],
    "contact_relations": [
       {
           "contact_id": "02bdc9f6-4dfb-479e-84ba-f6c3b96c39ba",
           "is_primary":true
       }
    ]
}
```

![Opportunity inside the Pipeliner Application](/files/wFQGluIwe0DO500BKtPL)

**Possible problems**

| Error description                                                              | Resolution                                                                                                                                                                                                                                  |
| ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Error on field account\_relations. Exactly one 'is\_primary' item must be set. | <p>Use <code>is\_primary</code> flag for Account/Contact relation object. </p><p>-When creating account relations at least one Account needs to be primary<br>-When creating contact relations at least one Contact needs to be primary</p> |


# Create Product, Product Line Item

This tutorial should help you to Create Products (Upload Products to Coevera). Before moving forward, make sure your [**Authentication** ](/api-docs/overview/authentication)works and you understand the [**Key Concepts**](/api-docs/core-api-concepts/understanding-the-crm-concept) of the Coevera API, and make sure you know how to use [**API parameters**](/api-docs/core-api-concepts/api-parameters)

**The Product** represents the physical or virtual thing that your company sells. Product is usually defined by name, by SKU (unique identification, stock-keeping unit), and by some other properties like category, unit, etc. **Products** and their management can be found in Administration.

**The Product Line item** represents specific relation between Product & Opportunity. At the moment when the Product is linked with the opportunity, we call this relation Product Line Item. On this relation, your salespeople define the Price, Discounts of the Product. **Product Line items** can be found on Opportunities

![Products: Management of Products is located in Admistration](/files/dVvj3QewxBp9AOo6qYFp)

![Product Line Items: Products can be used on Opportunities by salespeople, when selling to the Customers](/files/NGNnCjfjCOptAxL04C07)

## Products - Tutorial Assignment <a href="#tutorial-assignment" id="tutorial-assignment"></a>

Create new Products in Coevera with correct Product Properties like Product name, SKU, product category.

### 0. Required fields <a href="#id-0.-required-fields" id="id-0.-required-fields"></a>

<table><thead><tr><th width="251.76811427063683">Required API field Name</th><th>Description</th></tr></thead><tbody><tr><td>name</td><td>Name of the Account</td></tr><tr><td>allowed_pipelines</td><td>Select on which Opportunity Pipelines the product should be enabled. Use <code>1</code> for All Pipelines (recommended)</td></tr><tr><td>unit_symbol</td><td>The name of the unit of measure for the product. You can use custom values like pounds, hours, h, kgs , etc.</td></tr></tbody></table>

### 1.  Prepare Data

**Product\_*****category\_*****id**

It is optional to use the Product category when creating products. Product category helps to organize products to groups/product families with similar properties like (engines, wheels, etc.). Use the following reguest to retrieve ProductCategories

```
GET
{{baseUrl}}/entities/ProductCategories
```

### **2**.  Create products

We are going to use [**Bulk create method**](/api-docs/core-api-concepts/bulk-create-update-delete) to create more Products in the Coevera application at once.

{% openapi src="/files/483oBiKgEGR3bPMLT8VK" path="/entities/Products/batch-modify" method="post" %}
[openapi (1).json](https://3470708952-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFpjbhrh1xo0SPAbAc7Ny%2Fuploads%2FOlNVdYj1h5GSxQmLHAjz%2Fopenapi%20\(1\).json?alt=media\&token=4be07353-5170-4a95-9100-4f16545d47b0)
{% endopenapi %}

```json
[
    {
        "name": "Product 1",
        "allowed_pipelines": 1,
        "unit_symbol": "kg"
    },
    {
        "name": "Product 2",
        "allowed_pipelines": 1,
        "unit_symbol": "pcs"
    },
    {
        "name": "Product 3",
        "allowed_pipelines": 1,
        "unit_symbol": "hours"
    }
]
```

```json
{
    "success": true,
    "data": [
        "703c7426-c197-4441-beb7-201609ee47af",
        "c4d2428f-f8ef-4f27-abdb-aaf3fe626a89",
        "3648bf8a-6ad8-4057-b404-5d01bfac7dff"
    ]
}
```

![](/files/1ABjkEPsImUqs6mnXi2w)

## Product Line Items - Tutorial Assignment <a href="#tutorial-assignment" id="tutorial-assignment"></a>

Create Opportunity with Product Line items (Product Line Items). Set a correct Price, discount for each of the Product Line items.

Before jumping to this tutorial, you should already understand the process of creating Opportunities inside the Pipeliner Application. If you don´t, read  [**Create Opportunity** ](/api-docs/tutorials-and-articles/create-opportunity)tutorial beforehand.

{% hint style="success" %}
Working with Product Line items is supported by this Endpoint **{{baseURL}}/entities/OpptyProductRelations/**
{% endhint %}

### Basic Use Case: Create Product Line Items on Opportunity <a href="#id-0.-required-fields" id="id-0.-required-fields"></a>

We are going to use the Opportunity values that we prepared in the tutorial [**Create Opportunity**](/api-docs/tutorials-and-articles/create-opportunity)**.** For Product Line items we need to specify a new attribute in the JSON body - `product_relations.` This attribute represents the list of products that are going to be linked with the Newly created Opportunity and newly created products from the previous tutorial [**Products - Tutorial Assignment**](#tutorial-assignment)**.**&#x20;

```json
{
    "closing_date": "2019-01-01",
    "name": "New Opportunity",
    "owner_id": "00000000-0000-0000-0000-000000011a7d",
    "step_id": "de115511-5dc1-46c3-86d9-f714457208dd",
    "value": {
        "base_value": 100,
        "currency_id": "c4ca4238-a0b9-0382-0dcc-509a6f75849b"
    },
    "account_relations": [
       {
           "account_id": "0bc376a4-c579-413a-9221-e86e4a134766",
           "is_primary": true
           
       }
    ],
    "contact_relations": [
       {
           "contact_id": "02bdc9f6-4dfb-479e-84ba-f6c3b96c39ba",
           "is_primary":true
       }
    ],
    "product_relations" : [
        {
            "product_id": "703c7426-c197-4441-beb7-201609ee47af",
            "price": 10
        },
        {
            "product_id": "c4d2428f-f8ef-4f27-abdb-aaf3fe626a89",
            "price": 20
        },
        {
            "product_id": "3648bf8a-6ad8-4057-b404-5d01bfac7dff",
            "price": 30
        }
    ]
}
```

![Example how the Product Line items look on Opportunity](/files/FuKmkR6lRVcG0NQLODAe)

### Other Use Cases

#### Automatically update the final Opportunity value from Products

This is really helpful when your business calculates Opportunity Values only from Products on Opportunity. Then define an opportunity attribute `"is_value_auto_calculate": true`

![Auto calculation of Price is Enabled](/files/MV0XBbqpiRNq0XeDUcSZ)

#### Use prices from Product Pricelist

When your sales team updates the pricelist frequently or you don´t know the actual price of the product, you can use Pricelist from Pipeliner to get the Prices automatically, by this opportunity attribute: `"product_price_list_id": "id of product pricelist"`

To get a product price list ID use this request

```
GET
{{baseURL}}/entities/ProductPriceLists
```

```json
{
    "closing_date": "2019-01-01",
    "product_price_list_id": "4c4cf9ab-972a-40bb-a749-74fc64289e52",
    "name": "New Opportunity",
    "owner_id": "00000000-0000-0000-0000-000000011a7d",
    "step_id": "de115511-5dc1-46c3-86d9-f714457208dd",
    "is_value_auto_calculate": true,
    "value": {
        "base_value": 100,
        "currency_id": "c4ca4238-a0b9-0382-0dcc-509a6f75849b"
    },
    "account_relations": [
       {
           "account_id": "0bc376a4-c579-413a-9221-e86e4a134766",
           "is_primary": true
           
       }
    ],
    "contact_relations": [
       {
           "contact_id": "02bdc9f6-4dfb-479e-84ba-f6c3b96c39ba",
           "is_primary":true
       }
    ],
    "product_relations" : [
        {
            "product_id": "703c7426-c197-4441-beb7-201609ee47af"
        },
        {
            "product_id": "c4d2428f-f8ef-4f27-abdb-aaf3fe626a89"
        },
        {
            "product_id": "3648bf8a-6ad8-4057-b404-5d01bfac7dff"
        }
    ]
}
```

![Product 1..3 prices in PriceList](/files/f2fZRXLcYU6s3zsGw0Xp)

![Prices are automatically popupalted for a specified pricelist](/files/TJAAEMeUQsM2WSgNMb5r)


# Create Custom Entity Record

This tutorial should help you create the first Custom Entity record. Before moving forward, make sure your [**Authentication** ](/api-docs/overview/authentication)works and you understand the [**Key Concepts**](/api-docs/core-api-concepts/understanding-the-crm-concept) of the Coevera API and make sure you know how to use [**API parameters**](/api-docs/core-api-concepts/api-parameters)

**The Custom Entity** allows user to work with a completely new type of entity in Coevera. You can create Custom Entity records and link them with other entities using Lookup fields.

## Tutorial Assignment

* Create Custom Entity record with the particular Entity Type&#x20;
* Link Custom Entity record to Opportunity using Lookup field
* Filter existing Custom entity record by custom field

### 0.  Required fields

<table><thead><tr><th width="308.2672043757614">Required API field Name</th><th>Description</th></tr></thead><tbody><tr><td>name</td><td>Name of the custom entity record</td></tr><tr><td>owner_id</td><td>Id of the User in Coevera Application</td></tr><tr><td>type_id</td><td>Id of the related Custom Entity Expected Closing date.</td></tr></tbody></table>

### 1.  Prepare Data

#### Owner\_id

Load an id of the user with the [default sales unit](/api-docs/core-api-concepts/understanding-the-crm-concept#users-and-roles-and-sales-units-accessing-records). This user will become the owner of the newly created Custom Entity Record.

{% openapi src="/files/483oBiKgEGR3bPMLT8VK" path="/entities/Clients" method="get" %}
[openapi (1).json](https://3470708952-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFpjbhrh1xo0SPAbAc7Ny%2Fuploads%2FOlNVdYj1h5GSxQmLHAjz%2Fopenapi%20\(1\).json?alt=media\&token=4be07353-5170-4a95-9100-4f16545d47b0)
{% endopenapi %}

```
{{baseUrl}}/entities/Clients?load-only=id,default_unit_id&filter[email]=john.doe@example.com
```

```json
{
            "id": "00000000-0000-0000-0000-000000011a7d",
            "default_unit_id": "aba4a358-f3f8-4f55-b3ed-dd5cf589103b"
}
```

{% hint style="info" %}
We don´t necessarily need to load the default unit id. If only owner\_id is specified in the final request, Coevera will automatically create the opportunity with the default User´s sales unit.  (See step 2. of this tutorial)
{% endhint %}

#### Type\_id

Pull Custom Entity Types. Store the ID of the Custom Entity Type

{% openapi src="/files/1ssMTkhgAMUbxs9Y70kx" path="/entities/{custom\_entity\_api\_name}Type" method="get" %}
[openapi\_2023\_09\_27\_3.json](https://3470708952-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFpjbhrh1xo0SPAbAc7Ny%2Fuploads%2FLAy3xMsdxwYMX3PYxYuJ%2Fopenapi_2023_09_27_3.json?alt=media\&token=2b57d3c5-14b3-4807-9ee6-98eb2dec651b)
{% endopenapi %}

```
{{baseUrl}}/entities/MyCustomEntityType
```

```json
 
{
	"is_delete_protected": true,
	"has_draft": false,
	"id": "00000000-0000-0000-0000-000000000002",
	"is_deleted": false,
	"modified": "2023-09-20 07:08:32.528011+00:00",
	"created": "2023-09-11 08:38:36.498033+00:00",
	"form_edit": {
	},
	"form_edit_api": {
	},
	"is_readonly": false,
	"name": "Custom entity 1",
	"is_published": true,
	"revision": 4288,
	"entity_api_name": "MyCustomEntity"
},
{
	"is_delete_protected": false,
	"has_draft": false,
	"id": "018ad56d-879c-b0dd-3c3a-75c59ab97a23",
	"is_deleted": false,
	"modified": "2023-09-27 06:57:23.126262+00:00",
	"created": "2023-09-27 06:57:19.772625+00:00",
	"form_edit": "",
	"form_edit_api": {
	},
	"is_readonly": false,
	"name": "Custom entity 2",
	"is_published": true,
	"revision": 4461,
	"entity_api_name": "MyCustomEntity"
}
```

### 2. Create Custom Entity record

Let´s Take data from Step 1. and use them in the following request to create a Custom Entity record.

{% openapi src="/files/1ssMTkhgAMUbxs9Y70kx" path="/entities/{custom\_entity\_api\_name}" method="post" %}
[openapi\_2023\_09\_27\_3.json](https://3470708952-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFpjbhrh1xo0SPAbAc7Ny%2Fuploads%2FLAy3xMsdxwYMX3PYxYuJ%2Fopenapi_2023_09_27_3.json?alt=media\&token=2b57d3c5-14b3-4807-9ee6-98eb2dec651b)
{% endopenapi %}

```json
{
	"name": "Custom Entity Record 3",
	"owner_id": "00000000-0000-0000-0000-000000011a7d",
	"type_id": "018ad56d-879c-b0dd-3c3a-75c59ab97a23"
}
```

Success response

```json
{
	"success": true,
	"data": {
		"is_delete_protected": false,
		"id": "018ad5a4-2ea8-75f0-e8cc-c6e54688b165",
		"modified": "2023-09-27 07:57:01.480723+00:00",
		"created": "2023-09-27 07:57:01.480781+00:00",
		"owner": "http://example.com",
		"type": "http://example.com",
		"unit": "http://example.com",
		"name": "Custom Entity Record 3",
		"owner_id": "00000000-0000-0000-0000-000000011a7d",
		"share_mode": 0,
		"table_name": "ce_custom_entity1n",
		"type_id": "018ad56d-879c-b0dd-3c3a-75c59ab97a23",
		"unit_id": "7d9467e0-d885-4729-877e-5c9e1e057b4a",
		"is_deleted": false,
		"sharing_units": [],
		"sharing_clients": [],
		"documents": [],
		"is_favorite": false,
		"revision": 4464,
		"cf_high_priority": true,
		"cf_lookup_ce_mycustomentity_leadoppty": []
	}
}
```

### 3. Link Custom Entity record to existing record using Lookup field

Take data from Step 2. and use them in the following request, to link existing record to Opportunity using a Lookup field.

#### Get Opportunity\_id

We are going to search for Opportunity by name. But you can use whatever parameter.

{% openapi src="/files/1ssMTkhgAMUbxs9Y70kx" path="/entities/Opportunities" method="get" %}
[openapi\_2023\_09\_27\_3.json](https://3470708952-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFpjbhrh1xo0SPAbAc7Ny%2Fuploads%2FLAy3xMsdxwYMX3PYxYuJ%2Fopenapi_2023_09_27_3.json?alt=media\&token=2b57d3c5-14b3-4807-9ee6-98eb2dec651b)
{% endopenapi %}

```
{{baseUrl}}/entities/Opportunities?filter-op[name]=contains&filter[name]=Accounting
```

```json
{
        "is_delete_protected": false,
        "id": "0188d953-0aa6-1094-f764-1ce141993b26",
        "is_deleted": false,
        "modified": "2023-06-20 15:01:18.162394+00:00",
        "created": "2023-06-20 15:01:18.118462+00:00",
        "active_quote": null,
        "oppty_type": "http://example.com",
        "owner": "http://example.com",
        "product_currency": "http://example.com",
        "product_price_list": null,
        "reason_of_close": null,
        "step": "http://example.com",
        "unit": "http://example.com",
        "active_quote_id": null,
        "closing_date": "2023-06-21",
        "description": "",
        "is_archived": false,
        "is_value_auto_calculate": false,
        "label_flag": 0,
        "name": "Double Entry Accounting Services",
        "oppty_type_id": "0c03f112-4544-06a8-b162-1f14524c149c",
        "owner_id": "00000000-0000-0000-0000-000000011a7d",
        "product_currency_id": "c4ca4238-a0b9-0382-0dcc-509a6f75849b",
        "ranking": 50,
        "reason_of_close_description": "",
        "reason_of_close_id": null,
        "share_mode": 0,
        "step_id": "5854307d-d86e-4b97-be3f-a2c19f85ff07",
        "table_name": "oppty",
        "unit_id": "7d9467e0-d885-4729-877e-5c9e1e057b4a",
        "was_qualified": false,
        "revision": 3584,
        "value": {
        "base_value": 10000,
        "currency_id": "36665823-00d8-401f-b7d2-8e0736c3beb2",
        "value_foreign": 12500
        },
        "oppty_recurrence": null,
        "revenue_schedule": null,
        "product_relations": [],
        "primary_contact": null,
        "primary_account": "http://example.com",
        "contact_relations": [],
        "account_relations": [
                "http://example.com"
        ],
        "documents": [],
        "quote_relations": [],
        "status": 1,
        "qualify_date": null,
        "won_date": null,
        "lost_date": null,
        "days_in_step": 68,
        "is_favorite": false,
        "sharing_units": [],
        "sharing_clients": [],
        "tags": [],
        "formatted_name": "Double Entry Accounting Services",
        "modified_by_user": null
}
```

**Create a linking between Custom Entity record and Opportunity**

{% openapi src="/files/1ssMTkhgAMUbxs9Y70kx" path="/entities/{custom\_entity\_api\_name}/{id}" method="patch" %}
[openapi\_2023\_09\_27\_3.json](https://3470708952-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFpjbhrh1xo0SPAbAc7Ny%2Fuploads%2FLAy3xMsdxwYMX3PYxYuJ%2Fopenapi_2023_09_27_3.json?alt=media\&token=2b57d3c5-14b3-4807-9ee6-98eb2dec651b)
{% endopenapi %}

```json
{
	"cf_lookup_ce_mycustomentity_leadoppty": "0188d953-0aa6-1094-f764-1ce141993b26"
}
```

Success response

```json
{
		"is_delete_protected": false,
		"id": "018ad5a4-2ea8-75f0-e8cc-c6e54688b165",
		"modified": "2023-09-27 07:57:01.480723+00:00",
		"created": "2023-09-27 07:57:01.480781+00:00",
		"owner": "http://example.com",
		"type": "http://example.com",
		"unit": "http://example.com",
		"name": "Custom Entity Record 3",
		"owner_id": "00000000-0000-0000-0000-000000011a7d",
		"share_mode": 0,
		"table_name": "ce_custom_entity1n",
		"type_id": "018ad56d-879c-b0dd-3c3a-75c59ab97a23",
		"unit_id": "7d9467e0-d885-4729-877e-5c9e1e057b4a",
		"is_deleted": false,
		"sharing_units": [],
		"sharing_clients": [],
		"documents": [],
		"is_favorite": false,
		"revision": 4464,
		"cf_priority": 2,
		"cf_lookup_ce_mycustomentity_leadoppty": [
				"id": "0188d953-0aa6-1094-f764-1ce141993b26",
				"name": "Double Entry Accounting Services",
				"picture_url": null,
				"entity_name": "Opportunity",
				"entity_api_name": null,
				"entity_type_id": null,
				"is_deleted": false,
				"is_available": true
		]
}
```

### 4. Filter existing Custom Entity record by custom field

Filter Custom Entity records using the specific conditions.

{% openapi src="/files/1ssMTkhgAMUbxs9Y70kx" path="/entities/{custom\_entity\_api\_name}" method="get" %}
[openapi\_2023\_09\_27\_3.json](https://3470708952-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFpjbhrh1xo0SPAbAc7Ny%2Fuploads%2FLAy3xMsdxwYMX3PYxYuJ%2Fopenapi_2023_09_27_3.json?alt=media\&token=2b57d3c5-14b3-4807-9ee6-98eb2dec651b)
{% endopenapi %}

```json
{{baseUrl}}/entities/MyCustomEntity?filter-op[cf_priority]=gt&filter[cf_priority]=3
```

Success response

```json
{
		"is_delete_protected": false,
		"id": "012bc5a7-23e8-15a0-a51b-e6c5462eb415",
		"modified": "2023-09-27 07:32:01.480723+00:00",
		"created": "2023-09-27 07:32:01.480781+00:00",
		"owner": "http://example.com",
		"type": "http://example.com",
		"unit": "http://example.com",
		"name": "Custom Entity Record 1",
		"owner_id": "00000000-0000-0000-0000-000000011a7d",
		"share_mode": 0,
		"table_name": "ce_custom_entity1n",
		"type_id": "018ad56d-879c-b0dd-3c3a-75c59ab97a23",
		"unit_id": "7d9467e0-d885-4729-877e-5c9e1e057b4a",
		"is_deleted": false,
		"sharing_units": [],
		"sharing_clients": [],
		"documents": [],
		"is_favorite": false,
		"revision": 4364,
		"cf_priority": 4,
		"cf_lookup_ce_mycustomentity_leadoppty": []
}
```


# Upload Document

This tutorial should help you upload the first Document. Before moving forward, make sure your [**Authentication** ](/api-docs/overview/authentication)works and you understand the [**Key Concepts**](/api-docs/core-api-concepts/understanding-the-crm-concept) of the Coevera API, and make sure you know how to use [**API parameters**](/api-docs/core-api-concepts/api-parameters)

**The Documents** represent the physical file (.docx, .pdf, etc.) that can be linked to records in Coevera

![Documents can be found on almost all Main Coevera Entities](/files/qmqBRfPbzSAFvsCFxCRb)

## Tutorial Assignment <a href="#tutorial-assignment" id="tutorial-assignment"></a>

Upload Document to the Account.

### 0. Required fields <a href="#id-0.-required-fields" id="id-0.-required-fields"></a>

<table><thead><tr><th width="251.76811427063683">Required API field Name</th><th>Description</th></tr></thead><tbody><tr><td>filename</td><td>Name of the Document</td></tr><tr><td>content</td><td>The image in base64 encoded string value.</td></tr><tr><td>type</td><td><p>Required. Integer enum values are:</p><p><strong>1</strong> – S3File (recommended - Coevera Storage)  </p><p><strong>2</strong> – S3Image (Coevera Storage), </p><p><strong>3</strong> – GoogleDriveFile, </p><p><strong>4</strong> – OneDriveFile, </p><p><strong>5</strong> – BoxFile, </p><p><strong>6</strong> – DropboxFile, </p><p><strong>7</strong> – SharepointFile, </p><p><strong>8</strong> – ExternalURL.</p></td></tr></tbody></table>

### 1.  Prepare Data

#### Account\_id

As we are going to upload document to a specific account, we need to retrieve its ID

```
{{baseUrl}}/entities/Accounts?include-deleted=false&filter[email1]=info@ziemann-and-sons.de
```

```json
{
            "is_delete_protected": false,
            "id": "0bc376a4-c579-413a-9221-e86e4a134766",
            "is_deleted": false,
            "modified": "2019-02-01 10:01:23.011709+00:00",
            "created": "2019-01-30 11:44:23.586083+00:00",
            "account_type": "https://us-east.pipelinersales.com/api/v100/rest/spaces/nv3_PipelinerDev/entities/AccountTypes/a456236f-6f23-0908-abfd-384aa0f62f9e",
            "customer_type": "https://us-east.pipelinersales.com/api/v100/rest/spaces/nv3_PipelinerDev/entities/Data/04444b3a-c669-03bc-2c49-bcd7f047d41a",
            "industry": "https://us-east.pipelinersales.com/api/v100/rest/spaces/nv3_PipelinerDev/entities/Data/acbda72f-2054-0b71-9d42-cb35aaa37600",
            "owner": "https://us-east.pipelinersales.com/api/v100/rest/spaces/nv3_PipelinerDev/entities/Clients/00000000-0000-0000-0000-000000011a3d",
            "parent_account": null,
            "parent_account_relation_type": null,
            "picture": "https://us-east.pipelinersales.com/api/v100/rest/spaces/nv3_PipelinerDev/entities/CloudObjects/5ddfe953-a569-48e1-86bb-271e6506e7d0",
            "unit": "https://us-east.pipelinersales.com/api/v100/rest/spaces/nv3_PipelinerDev/entities/SalesUnits/ea33e8fb-9a56-4802-a175-2d1f406af7cf",
            "account_class": 5,
            "account_type_id": "a456236f-6f23-0908-abfd-384aa0f62f9e",
            "address": "7 Lillian Plaza",
            "city": "Coronda",
            "comments": "",
            "country": "Argentina",
            "customer_type_id": "04444b3a-c669-03bc-2c49-bcd7f047d41a",
            "email1": "info@ziemann-and-sons.de",
            "email2": "",
            "email3": "",
            "email4": "",
            "email5": "",
            "health_category": null,
            "health_status": null,
            "home_page": "www.ziemannandsons.com",
            "industry_id": "acbda72f-2054-0b71-9d42-cb35aaa37600",
            "name": "Ziemann and Sons",
            "owner_id": "00000000-0000-0000-0000-000000011a3d",
            "parent_account_id": null,
            "parent_account_relation_type_id": null,
            "phone1": "+1 (888) 500-8000",
            "..."
        }
```

### 2.  Upload Document

Uploading document consists of two steps, but we can actually accomplish this in one request:&#x20;

1. Upload document to the Storage
2. Link Document to Account

#### Upload document & linking in one step

In this step, we will upload a document and immediately link that to the Account

{% openapi src="/files/483oBiKgEGR3bPMLT8VK" path="/entities/CloudObjectRelations" method="post" %}
[openapi (1).json](https://3470708952-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFpjbhrh1xo0SPAbAc7Ny%2Fuploads%2FOlNVdYj1h5GSxQmLHAjz%2Fopenapi%20\(1\).json?alt=media\&token=4be07353-5170-4a95-9100-4f16545d47b0)
{% endopenapi %}

```json
{
    "cloud_object": {
        "filename": "New PDF File.pdf",
        "type": 1,
        "content": "Content in basa64"
    },
    "account_id": "0bc376a4-c579-413a-9221-e86e4a134766"
}
```

{% hint style="info" %}
It is recommended to include the **File Type** in the file name of the document (like \*.pdf, \*.jpg). Then Pipeliner can automatically recognize the format that helps sales people with the opening of documents
{% endhint %}

![](/files/GHfqq3C8eViQ14jVnV6U)

#### Uploading files from external storage

If you wish to upload files that are stored in external storage like (Sharepoint, Google drive) you can do that by changing the `type` attribute. In our case, we are going to Upload a document to Pipeliner that is stored on Google Drive storage.

The list of all `types`

**1** – S3File (recommended - Pipeliner Storage) &#x20;

**2** – S3Image (Pipeliner Storage),&#x20;

**3** – GoogleDriveFile,&#x20;

**4** – OneDriveFile,&#x20;

**5** – BoxFile,&#x20;

**6** – DropboxFile,&#x20;

**7** – SharepointFile,&#x20;

**8** – ExternalURL.

For Uploading external files, you need to specify the `url` instead of `content` attribute

```json
{
    "cloud_object": {
        "filename": "File from google drive",
        "type": 3,
        "url": "https://docs.google.com/spreadsheets/d/1qDQJPID0UHkGywAoopWLYMWHGVDwCo0M2nov-XmzU-Q/edit?usp=sharing"
    },
    "account_id": "0bc376a4-c579-413a-9221-e86e4a134766"
}
```

![](/files/QSoi5q7DsnYn7yLYQ37U)


# Merging Accounts/Contacts

This tutorial should help you merge Accounts or Contact. Before moving forward, make sure your [**Authentication** ](/api-docs/overview/authentication)works and you understand the [**Key Concepts**](/api-docs/core-api-concepts/understanding-the-crm-concept) of the Coevera API, and make sure you know how to use [**API parameters**](/api-docs/core-api-concepts/api-parameters)

When you have two similar Accounts or Contacts you can use merge functionality to move all data from a duplicate to the master record. The Duplicate will be deleted at the same time

#### Merging Accounts

{% openapi src="/files/483oBiKgEGR3bPMLT8VK" path="/entities/Accounts/merge" method="post" %}
[openapi (1).json](https://3470708952-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFpjbhrh1xo0SPAbAc7Ny%2Fuploads%2FOlNVdYj1h5GSxQmLHAjz%2Fopenapi%20\(1\).json?alt=media\&token=4be07353-5170-4a95-9100-4f16545d47b0)
{% endopenapi %}

#### Merging Contacts

{% openapi src="/files/483oBiKgEGR3bPMLT8VK" path="/entities/Contacts/merge" method="post" %}
[openapi (1).json](https://3470708952-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFpjbhrh1xo0SPAbAc7Ny%2Fuploads%2FOlNVdYj1h5GSxQmLHAjz%2Fopenapi%20\(1\).json?alt=media\&token=4be07353-5170-4a95-9100-4f16545d47b0)
{% endopenapi %}

**Example of Account Merging**

The merging functionality through API works in the same way as[ **in the Application.**](https://help.pipelinersales.com/en/articles/3834458-merging-accounts-and-contacts)

```
/POST /entities/Accounts/merge
{
    "master": {
        "id": "4590b5a8-134a-404e-96f5-b40256bebc39"
    },
    "secondary_ids": [
        "109e5d1c-6d10-449b-b244-28438a428926"
    ]
}
```

`master-` This record will inherit data from a duplicate defined in secondary\_ids

`secondary_ids -` An Array of Duplicates, use Account IDs to specify the Account&#x73;**.** All duplicates are automatically deleted


