PO's and PO Changes Integration into your ERP

Step-by-step instructions to integrate your Coupa PO's and PO Changes with your ERP.

Introduction

You can also download this document as a Microsoft Word document: Coupa Purchase Orders to ERP.docx

General API setup considerations

Limited payload - fields & API filters

Coupa's API returns a lot of data by default (for example: full objects for associated objects). The API return payloads can be very large and therefore slow. 

To make things easier, Coupa includes a Fields query parameter and API Filters to return a limited JSON or XML response instead of the entire schema and all associations for an object. For more information, see API Response Filters.

Use cases described in this article

The assumption in this document is that the Purchase Order number in the ERP is driven by the Coupa Purchase Order Number. This Article describes three different options to Integrate Coupa Purchase Orders into your ERP (for both creation and updates). 

These options will change the way you can monitor your integrations from Coupa:

  • Option 1: Simple monitoring based on custom field(s) you define on the Order Header
  • Option 2: Advanced monitoring using Integration History records
  • Option 3: Leverage full Coupa integration monitoring

For the three options, the Coupa POs are pushed to the ERP based on the Export flag.

In case of an error, in the Integration of a PO, a manual change will be required on the PO in the Coupa UI: this change will reset the Export flag, and the PO will therefore be considered in the next run.

Tip

You can contact Coupa Support to enable this option: Reset PO last exported at for every change. This setting only applies to the UI. Changes made with API won’t change the Exported status.

Create dedicated Integration and Contact for API

For option 2 & 3 described above, you need to create:

  1. A dedicated Integration for each API Orchestration you implement.
  2. One or several Integration contact(s) for each integration, that will be alerted for any failed integration.
Tip

You can contact Coupa Support to enable this option: Enable link to Integration History by Document Type. This setting adds a link in the setup page to view full Integration History per document type

Option 1: Simple monitoring based on custom field(s)

Description

In this scenario, for each PO we will add the current Integration status in one or several PO header custom field(s). We added a custom field cf-integration-status with the name of Integration Status. Use the Standard PO Data Table to follow up the Integration status of your documents at this url: https://<your instance hostname>/order_headers.

Purchase Orders table

Orchestration diagram

Orchestration diagram

Steps / API calls details

Step 1

Get the list and details of the Coupa Purchase Orders to create/update in the ERP.
Selection criteria includes the Export Flag and PO Status.
Query parameter show_deleted_lines can be necessary to handle the PO update in the ERP

Method

GET

API

https://<your instance hostname>/api/purchase_orders/

Query Params

filter=<your API filter name>
offset=10
exported=false
show_deleted_lines=true*
status[in]=issued,canceled,closed

Sample URL

https://<your instance hostname>/api/purchase_orders?filter=<your API filter name>&offset=10&exported=false&show_deleted_lines=true&status[in]=issued,canceled,closed

Response body sample

Response body sample

Note

The show_deleted_lines=true query parameter is for PO changes.

Step 2

Mark individual PO as exported

Method

PUT

API

https://<your instance hostname>/api/purchase_orders/<Purchase Order id>

Query Params

exported=true
fields=["id","exported"]

Sample URL

https://<your instance hostname>/api/purchase_orders/<Purchase Order id>?exported=true&fields=["id","exported"]

Query Body sample

N/A *

Response Body sample


{
	"id": <Purchase Order id>,
	"exported": true
	}
Note

For this call you do not need a payload if you include ?exported=true in the URL. That’s where the creation/update of the PO in the ERP happens.
 

Step 3

Update a Custom Fields for Reporting

Method

PUT

API

https://<your instance hostname>/api/purchase_orders/<Purchase Order id>

Query Params

fields=["id","exported",{ "custom_fields": {} }]

Sample URL

https://<your instance hostname>/api/purchase_orders/<Purchase Order id>?fields=["id","exported",{ "custom_fields": {} }]

Query Body sample


{ "custom-fields": {
		"<your custom-field name>": "Success: The PO was properly replicated in your ERP"
}}

or


{ "custom-fields": {
		"<your custom-field name>": "Error: The PO was properly replicated in your ERP"
}}

Response Body sample


{ "id": <Purchase Order id>,
		"exported": true,
		"custom-fields": {
				"<your custom-field name>": "Success: The PO was properly replicated in your ERP"
}}

or


{ "id": <Purchase Order id>,
		"exported": true,
		"custom-fields": {
				"<your custom-field name>": "Error: The PO was properly replicated in your ERP"
}}

Option 2: Advanced monitoring using Integration History

Description

In this scenario, for each PO we:

  • Resolve the previous Integration History Record for the document
  • Create an Integration History Record
  • Create an Alert to the Integration Contact in case of an error

Use the Standard PO Integration History Data Table to follow up the Integration status of your documents. You can find it at: https://<your instance hostname>/integration_history_records/purchase_orders.

You can use a filter on Response Code to differentiate between documents successfully replicated and documents that failed.

Orchestration Diagram

orchestration diagram

Steps / API calls details

Step 1

Get the list and details of the Coupa Purchase Orders to create/update in the ERP.
Selection criteria includes the Export Flag and PO Status.
Query parameter show_deleted_lines can be necessary to handle the PO update in the ERP

Method

GET

API

https://<your instance hostname>/api/purchase_orders/

Query Params

filter=<your API filter name>
offset=10
exported=false
show_deleted_lines=true
status[in]=buyer_hold,issued,canceled,closed,soft_closed

Sample URL

https://<your instance hostname>/api/purchase_orders?filter=<your API filter name>&offset=10&exported=false&show_deleted_lines=true&status[in]=buyer_hold,issued,canceled,closed,soft_closed

Response body sample

Response body sample

 

Step 2

Mark individual PO as exported

Method

PUT

API

https://<your instance hostname>/api/purchase_orders/<Purchase Order id>

Query Params

exported=true
fields=["id","exported"]

Sample URL

https://<your instance hostname>/api/purchase_orders/<Purchase Order id>?exported=true&fields=["id","exported"]

Query Body sample

N/A

Response Body sample


{
		"id": <Purchase Order id>,
		"exported": true
}

This is where the creation/update of the PO in the ERP happens.

Step 3a

Get unresolved Integration History Record

Method

GET

API

https://<your instance hostname>/api/integration_history_records

Query Params

resolved=false
document-type=OrderHeader
document-id=<Purchase Order id>
fields=["id","document-id","status","resolved"]

Sample URL

https://<your instance hostname>/api/integration_history_records?resolved=false&document-type=OrderHeader&document-id=<Purchase Order id>&fields=["id","document-id","status","resolved"]

Query Body sample

N/A

Response Body sample


[
		{
				"id": <Old Integration History Record id>,
				"document-id": <Purchase Order id>,
				"status": "Error",
				"resolved": false
		}
]

Step 3b

Resolve previous Integration History Record

Method

PUT

API

https://<your instance hostname>/api/integration_history_records/<Old Integration History Record id>/resolve

Query Params

fields=["id","document-id","status","resolved"]

Sample URL

https://<your instance hostname>/api/integration_history_records/<Old Integration History Record id>/resolve?fields=["id","document-id","status","resolved"]

Query Body sample

N/A

Response Body sample


[
		{
				"id": <Old Integration History Record id>,
				"document-id": <Purchase Order id>,
				"status": "Error",
				"resolved": true
		}
]

Step 4a

Create Integration History (Success)

Method

POST

API

https://<your instance hostname>/api/integration_history_records

Query Params

fields=["id","document-id","status"]

Sample URL

https://<your instance hostname>/api/integration_history_records?fields=["id","document-id","status"]

Query Body sample


{
		"document-type": "OrderHeader",
		"document-id": <Purchase Order id>,
		"document-status":"<Purchase Order status>",
		"contact-alert-type": "Functional",
		"status": "Success",
		"integration": {"code":"<Customer Integration id>"},
		"responses": [
				{
						"response-code": "Success-1234",
						"response-message": "The integration in the ERP went well"
				}
		]
}

Response Body sample


{
		"id": <New Integration History Record id>,
		"document-id": <Purchase Order id>,
		"status": "Success"
}

Step 4b

Create Integration History (Error) and alert to Integration Contact

Method

POST

API

https://<your instance hostname>/api/integration_history_records/create_alert

Query Params

fields=["id","document-id","status"]

Sample URL

https://<your instance hostname>/api/integration_history_records/create_alert?fields=["id","document-id","status"]

Query Body sample


{
		"document-type": "OrderHeader",
		"document-id": <Purchase Order id>,
		"document-status":"<Purchase Order status>",
		"contact-alert-type": "Functional",
		"status": "Error",
		"integration": {"code":"<Customer Integration id>"},
		"responses": [
				{
						"response-code": "Failure-CC",
						"response-message": "Line 1: Cost center CA234 is closed for ordering"
				},
				{
						"response-code": "Failure-date",
						"response-message": "Line 2: Delivery date cannot be in the past"
				}
		]
}

Response Body sample


{
		"id": <New Integration History Record id>,
		"document-id": <Purchase Order id>,
		"status": "Error"
}

Option 3: Leverage full Coupa integration monitoring

Description

In this scenario, we create an Integration run that tracks

  • The status of the Integration (pending/started/errored/successful/failed)
  • The total number of PO processed
  • The number of Success and Errors
  • The list of Integration Errors and their statuses (resolved or not)

For each PO we:

  • Resolve the previous Integration History Record for the document
  • Create an Integration History Record
  • In case of an error, create an Integration Error and an Alert to the Integration Contact

You can monitor all Integration Runs for your Integration at: https://<your instance hostname>/integrations/<your integration id>/integration_runs.

Use the Standard PO Integration Error Data Table to list all POs with Integration Error pending resolution. It's located at: https://<your instance hostname>/integration_errors.

Use the Standard PO Integration History Data Table to list all POs successfully Integrated. It's located at: https://<your instance hostname>/integration_history_records/purchase_orders.

Orchestration diagram

Orchestration diagram

Steps / API calls details

Step 1

Create Integration Run

Method

POST

API

https://<your instance hostname>/api/integration_runs

Query Params

N/A

Query Body sample


{
		"integration": {
				"code": "{{integration_code}}"
		}}

Response Body sample


{
		"id": <Integration Run ID>,
		...
}

Step 2

Get the list and details of the Coupa Purchase Orders to create/update in the ERP.
Selection criteria includes the Export Flag and PO Status.
Query parameter show_deleted_lines can be necessary to handle the PO update in the ERP

Method

GET

API

https://<your instance hostname>/api/purchase_orders/

Query Params

filter=<your API filter name>
offset=10
exported=false
show_deleted_lines=true
status[in]=buyer_hold,issued,canceled,closed,soft_closed

Sample URL

https://<your instance hostname>/api/purchase_orders?filter=<your API filter name>&offset=10&exported=false&show_deleted_lines=true&status[in]=buyer_hold,issued,canceled,closed,soft_closed

Response body sample

Step 3

Start Integration Run

Method

PUT

API

https://<your instance hostname>/api/integration_runs/<Integration Run ID>/run

Query Params

N/A

Query Body sample


{
		"total_records": <Total Number of POs from Step 2>
}

Response Body sample


{
		"id": <Integration Run ID>,
		...
}

Step 4

Mark individual PO as exported

Method

PUT

API

https://<your instance hostname>/api/purchase_orders/<Purchase Order id>

Query Params

exported=true
fields=["id","exported"]

Sample URL

https://<your instance hostname>/api/purchase_orders/<Purchase Order id>?exported=true&fields=["id","exported"]

Query Body sample

N/A

Response Body sample


{
		"id": <Purchase Order id>,
		"exported": true
}

This is where the creation/update of the PO in the ERP happens.

Step 5a

Get unresolved Integration History Record

Method

GET

API

https://<your instance hostname>/api/integration_history_records

Query Params

resolved=false
document-type=OrderHeader
document-id=<Purchase Order id>
fields=["id","document-id","status","resolved"]

Sample URL

https://<your instance hostname>/api/integration_history_records?resolved=false&document-type=OrderHeader&document-id=<Purchase Order id>&fields=["id","document-id","status","resolved"]

Query Body sample

N/A

Response Body sample


[
		{
				"id": <Old Integration History Record id>,
				"document-id": <Purchase Order id>,
				"status": "Error",
				"resolved": false
		}
]

Step 5b

Resolve previous Integration History Record

Method

PUT

API

https://<your instance hostname>/api/integration_history_records/<Old Integration History Record id>/resolve

Query Params

fields=["id","document-id","status","resolved"]

Sample URL

https://<your instance hostname>/api/integration_history_records/<Old Integration History Record id>/resolve?fields=["id","document-id","status","resolved"]

Query Body sample

N/A

Response Body sample


[
		{
				"id": <Old Integration History Record id>,
				"document-id": <Purchase Order id>,
				"status": "Error",
				"resolved": true
		}
]

Step 6a

Get unresolved Integration Error Record

Method

GET

API

https://<your instance hostname>/api/integration_errors

Query Params

resolved=false
document-type=OrderHeader
document-id=<Purchase Order id>

Sample URL

https://<your instance hostname>/api/integration_errors?resolved=false&document-type=OrderHeader&document-id=<Purchase Order id>

Query Body sample

N/A

Response Body sample


[
		{
				"id": <Old Integration Error Record id>,
				"document-type": ”OrderHeader”,
				"document-id": <Purchase Order id>,
				"status": "Error",
		"resolved": false
		...
		}
]

Step 6b

Resolve previous Integration History Record

Method

PUT

API

https://<your instance hostname>/api/integration_errors/<Old Integration Error Record id>/resolve

Query Params

N/A

Query Body sample

N/A

Response Body sample


[
		{
				"id": <Old Integration Error Record id>,
				"document-id": <Purchase Order id>,
				"status": "Error",
				"resolved": true
				...
		}
]

Step 7a

Create Integration History (Success)
It must reference the Integration Run

Method

POST

API

https://<your instance hostname>/api/integration_history_records

Query Params

fields=["id","document-id","status"]

Sample URL

https://<your instance hostname>/api/integration_history_records?fields=["id","document-id","status"]

Query Body sample


{
		"document-type": "OrderHeader",
		"document-id": <Purchase Order id>,
		"document-status":"<Purchase Order status>",
		"contact-alert-type": "Functional",
		"status": "Success",
		"integration": {"code":"<Customer Integration id>"},
		"integration-run": {"id":<Integration Run ID>},
		"responses": [
				{
						"response-code": "Success-1234",
						"response-message": "The integration in the ERP went well"
				}
		]}

Response Body sample


{
		"id": <New Integration History Record id>,
		"document-id": <Purchase Order id>,
		"status": "Success"
}

Step 7b

Create Integration Error and alert to Integration Contact
It must reference the Integration Run

Method

POST

API

https://<your instance hostname>/api/integration_errors/create_alert

Query Params

N/A

Query Body sample


{
		"document-type": "OrderHeader",
		"document-id": <Purchase Order id>,
		"document-status":"<Purchase Order status>",
		"contact-alert-type": "Functional",
		"status": "Error",
		"integration-run-id": "<Integration Run ID>",
		"responses": [
				{
						"response-code": "Failure-CC",
						"response-message": "Line 1: Cost center CA234 is closed for ordering"
				},
				{
						"response-code": "Failure-date",
						"response-message": "Line 2: Delivery date cannot be in the past"
				}
		]
}

Response Body sample


{
		"id": <New Integration Error Record id>,
		"document-id": <Purchase Order id>,
		"status": "Error"
		 ...
}

Step 8

Successfully End Integration Run

Method

PUT

API

https://<your instance hostname>/api/integration_runs/<Integration Run ID>/success

Query Params

N/A

Query Body sample

N/A

Response Body sample


{
		"id": <Integration Run ID>,
		"status": "successful"
		...
}

If there is a general failure during the Integration run

Step x

Raise Failure for the Integration Run

Method

PUT

API

https://<your instance hostname>/api/integration_runs/<Integration Run ID>/fail

Query Params

N/A

Query Body sample

N/A

Response Body sample


{
		"id": <Integration Run ID>,
		"status": "failed"
		...
}

 

Related Items


Querying Options

21 October 2016

See how you can use queries to quickly identify and pull the data you require.

Special Actions and API Notes

21 October 2016

Additional info on how to use the Coupa API.

Differences between XML and JSON in Coupa

16 December 2016

Arguments

24 April 2017

Learn about the types of arguments that Coupa supports in conjunction with operators.