Introduction
A wholly owned subsidiary of Meat & Livestock Australia, the Integrity Systems Company (ISC) is responsible for delivering the red meat industry’s on-farm assurance and through-chain traceability programs. These are the Livestock Production Assurance (LPA) program, and the National Livestock Identification System (NLIS) which together make up Australia’s red meat integrity system.
These programs are connected through LPA National Vendor Declarations (LPA NVDs), which link on-farm assurance to livestock traceability. This makes LPA NVDs the legal document guaranteeing the quality, safety and traceability of Australian red meat products.
The ISC is also responsible for the development and delivery of the Digital Value Chain Strategy which will ensure the Australian red meat industry can make better use of existing and new data. The strategy will deliver improved feedback systems for producers including Livestock Data Link (LDL), along with conducting research and development that seeks to find the best digital technology and database management systems that will strengthen our integrity systems over time.
ISC’s mission is to grow red meat value chain opportunities through integrity and information systems innovation. It is essential to enhance our systems and technologies to stay ahead of our global competitors, maintain our point of difference, and enable Australia’s red meat industry to capture price premiums from consumers and customers who are willing to pay more for higher levels of product assurance.
Our API’s are a combination of SOAP, REST and GraphQL. Our API has predictable, resource-oriented URLs, and uses HTTP response in combination with API Status codes to indicate API errors. We use built-in HTTP features, like HTTP verbs, which are understood by off-the-shelf HTTP clients. JSON and XML is returned in all API responses including errors.
For further information about ISCs APIs contact:
Peter Quigley
ISC Integrator Analyst
pquigley@integritysystems.com.au
02 9436 9246
eNVD
About eNVD
The Livestock Production Assurance (LPA) National Vendor Declaration (NVD) communicates the food safety and treatment status of sheep, cattle or goats every time they move – between properties, to saleyards, or to processors.
NVDs are a legal document that are key to Australian red meat’s traceability and market access. It is crucial that the NVD is filled out accurately. When users tick a box or answer a question on the LPA NVD, they are declaring their on-farm practices meet LPA requirements, and ultimately customer expectations.
Their tick must be backed up by accurate farm records. This is a pledge that the meat from their farm has been produced safely, ethically and meets biosecurity requirements – it means they they stand by what they sell.
The LPA electronic National Vendor Declaration (eNVD) system is a faster, easier way to complete livestock consignments. The eNVD system is not just a place to fill out a NVD – it is a system for completing all consignment paperwork digitally including livestock assurance and health declarations. The system will be continuously improved to create better experiences for users and add value to our industry’s integrity. For more information, visit the ISC website here.
1. Introduction
The eNVD (electronic National Vendor Declaration) API is a powerful tool that allows developers to integrate livestock consignment management functionality into their applications. It provides a comprehensive set of endpoints to create, manage, and retrieve consignment and template data.
This developer portal is designed for software developers, system integrators, and other technical professionals who want to leverage the eNVD API to build applications and services related to livestock consignment management.
1.1 The New Account Dynamic within eNVD
The eNVD system introduces a new account dynamic that simplifies user management and access control. Instead of managing multiple logins for different systems (e.g., LPA, NLIS), users now have a single myMLA login and profile that encompasses all their associated accounts.
Within a single myMLA login, a user can have multiple accounts, such as:
- LPA (Livestock Production Assurance) accounts*
- NLIS (National Livestock Identification System) accounts*
- Transporter accounts
- Viewer accounts
- Buyer accounts
*Linking of NLIS and LPA accounts to a myMLA user is not handled within the eNVD platform. To link these accounts, please direct the user to log into the myMLA dashboard and select to link their respective product accounts.
Each account is identified using a new eNVD Account Id (eNVDAccountId) and must be provided with any eNVD API request.
Different accounts are assigned different roles which determine the level of access an account has to the eNVD system. For example, LPA accounts are assigned the producer role, which is the only role with permission to create consignments.
More detail on the new eNVD roles and their permissions is covered in section 7 of this document.
2. Getting Started
To start using the eNVD API, you’ll need to set up your development environment and obtain the necessary credentials. Follow the steps below to get started:
- API Endpoints:
- UAT/Staging Environment:
https://api.uat.integritysystems.com.au/v2/graphql
- Production Environment:
https://api.integritysystems.com.au/v2/graphql
Choose the appropriate endpoint based on your development stage and requirements.
Authentication and Authorisation:
- The eNVD API uses myMLA as the identity provider and OAuth 2.0 for authentication and authorisation.
- To access protected resources and perform actions on behalf of users, you need to include an OAuth 2.0 access token in the
authorization
header of each API request. - Access tokens can be obtained by following the OAuth 2.0 authorisation Code flow, which involves redirecting the user to the myMLA login page, obtaining an authorisation code, and exchanging it for an access token.
Obtaining OAuth Client Credentials:
- To integrate your application with the eNVD API, you need to register your application and obtain OAuth client credentials (client ID and client secret).
- Contact the eNVD support team at support@integritysystems.com.au to request client credentials. Provide them with your application details and the intended use case.
API Request and Response Format:
- The eNVD API follows the GraphQL specification, which provides a flexible and efficient way to query and mutate data.
- API requests should be sent as POST requests to the appropriate endpoint, with the GraphQL query or mutation included in the request body.
- The request and response data format is JSON.
Once you have obtained the necessary credentials and set up your development environment, you’re ready to start making API requests and integrating the eNVD API into your application.
3. Authentication and authorisation
The eNVD API uses OAuth 2.0, with myMLA as the identity provider, to ensure secure access to protected resources and user data. OAuth 2.0 is an industry-standard protocol that allows users to grant limited access to their data without exposing their credentials.
The recommended OAuth flow for the eNVD API is the authorisation Code Flow, which provides a secure way to obtain access tokens and refresh tokens. This flow involves the following steps:
- Redirecting the user to the myMLA login page to authenticate and authorize your application.
- Obtaining an authorisation code upon successful authentication and authorisation.
- Exchanging the authorisation code for an access token and a refresh token.
- Using the access token to make authenticated API requests on behalf of the user.
- Using the refresh token to obtain a new access token when the current one expires.
The authorisation Code Flow provides several advantages, including:
- Improved security by keeping the client secret confidential and not exposing it to the client-side.
- Long-lived access tokens with a default expiration of 24 hours, reducing the need for frequent token refreshes.
- Refresh tokens that allow obtaining new access tokens without requiring the user to re-authenticate.
3.1 Generating an Access Token
To generate an access token using the authorisation Code Flow, follow these steps:
- Request the authorisation Code:
https://sso-s.mla.com.au/authorize?response_type=code&scope=openid profile email offline_access&client_id=<YOUR_CLIENT_ID>&redirect_uri=https://localhost:3030/callback&audience=https://api.uat.integritysystems.com.au/graphql&state=<Your State>
- Redirect the user to the myMLA authorisation endpoint with the necessary query parameters, including your client ID, redirect URI, and desired scopes.
- Example authorisation URL:
- For the UAT/Staging environment, use
https://sso-s.mla.com.au/authorize
- For the production environment, use
https://sso.mla.com.au/authorize
- For the UAT/Staging environment, use
- Exchange the authorisation Code for an Access Token:
curl -X POST 'https://sso-s.mla.com.au/oauth/token' \
--header 'Content-Type: application/x-www-form-urlencoded'\
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'redirect_uri=https://localhost:3030/callback' \
--data-urlencode 'client_id=<YOUR_CLIENT_ID>' \
--data-urlencode 'code=<authorisation_CODE>'
- After the user authenticates and authorizes your application, myMLA will redirect the user back to your specified redirect URI with an authorisation code.
- Make a POST request to the myMLA token endpoint, including the authorisation code, client ID, client secret, and redirect URI.
- For the UAT/Staging environment, use
https://sso-s.mla.com.au/oauth/token
- For the production environment, use
https://sso.mla.com.au/oauth/token
- For the UAT/Staging environment, use
- Use the Access Token:
authorisation: Bearer <ACCESS_TOKEN>
- Upon successful token exchange, myMLA will respond with an access token, refresh token, and other token metadata.
- Include the access token in the
authorization
header of your API requests as a bearer token:
Now you can make authenticated API calls to the eNVD API using the obtained access token.
3.2 Refreshing Access Tokens
curl -X POST 'https://sso-s.mla.com.au/oauth/token' \
--header 'Content-Type: application/x-www-form-urlencoded'\
--data-urlencode 'grant_type=refresh_token' \
--data-urlencode 'client_id=<YOUR_CLIENT_ID>' \
--data-urlencode 'refresh_token=<REFRESH_TOKEN>'
Access tokens have an expiration time, typically set to 24 hours. To continue making authenticated requests after the access token expires, you can use the refresh token to obtain a new access token without requiring the user to re-authenticate.
To refresh an access token:
Make a POST request to the myMLA token endpoint, including the refresh token, client ID, client secret, and grant type.
myMLA will respond with a new access token and refresh token.
Update your application to use the new access token for subsequent API requests.
Refresh tokens have a longer lifespan compared to access tokens, typically around 30 days. It’s important to securely store refresh tokens and handle them with care, as they can be used to obtain new access tokens without user interaction.
3.3 Optional PKCE Code Challenge
https://sso-s.mla.com.au/authorize?response_type=code&client_id=<YOUR_CLIENT_ID>&redirect_uri=https://localhost:3030/callback&scope=openid profile email offline_access&audience=https://api.uat.integritysystems.com.au/graphql&state=<YOUR_STATE>&code_challenge=<CODE_CHALLENGE>&code_challenge_method=S256
For enhanced security, you can optionally implement the Proof Key for Code Exchange (PKCE) extension to the authorisation Code Flow. PKCE adds an additional layer of protection against authorisation code interception attacks.
To use PKCE:
curl -X POST 'https://sso-s.mla.com.au/oauth/token' \
--header 'Content-Type: application/x-www-form-urlencoded'\
--data-urlencode 'grant_type=authorisation_code' \
--data-urlencode 'redirect_uri=https://localhost:3030/callback' \
--data-urlencode 'client_id=<YOUR_CLIENT_ID>' \
--data-urlencode 'code=<authorisation_CODE>' \
--data-urlencode 'code_verifier=<CODE_VERIFIER>'
By implementing PKCE, you add an extra layer of security to the authorisation process, mitigating the risk of authorisation code interception and replay attacks.
- Generate a code verifier and code challenge:
- The code verifier is a random string of characters.
- The code challenge is derived from the code verifier using the SHA256 hash function and base64url encoding.
Include the code challenge and code challenge method in the authorisation request:
When exchanging the authorisation code for an access token, include the code verifier in the token request:
4. The eNVD v2 API
To leverage the v2 eNVD API, there are a few key areas that have changed from your existing integration. This section will guide you through the necessary steps to migrate your application to the new API.
4.1 myMLA and eNVD User Registration
Users must create their myMLA account via the myMLA website (https://mymla.com.au/). Once they have registered their myMLA account, they will be able to link any of their existing NLIS or LPA accounts via the myMLA dashboard “linked services” menu.
After linking all services, users must also register themselves with the eNVD system. The easiest way to get users registered in the eNVD system is to direct them to the new eNVD website or mobile application. Once they sign in with their myMLA account, if they have not already registered, they will be stepped through the eNVD registration process.
4.2 Updating the API URL
The API endpoints have changed for the new eNVD API. Update your application to use the following URLs:
For the UAT/Staging environment:
Authentication endpoint:
https://sso-s.mla.com.au/authorize
API endpoint:
https://api.uat.integritysystems.com.au/v2/graphql
For the production environment:
Authentication endpoint:
https://sso.mla.com.au/authorize
API endpoint:
https://api.integritysystems.com.au/v2/graphql
4.3 Changing Authentication/authorisation Flows
The new eNVD API uses OAuth 2.0 with the authorisation Code Flow for authentication and authorisation. You will need to update your application to follow this flow:
- Redirect the user to the myMLA authorisation endpoint to obtain an authorisation code.
- Exchange the authorisation code for an access token and refresh token.
- Use the access token to make authenticated API requests.
- Use the refresh token to obtain a new access token when the current one expires.
Refer to section 3 of this document for detailed instructions on implementing the OAuth 2.0 authorisation Code Flow.
4.4 Using the System
- Users must ’log in’ to the eNVD system to use the APIs correctly. There are two scenarios on login:
- User is registered in the eNVD system: The user will be able to use the new eNVD API.
- User is not registered in the eNVD system: The user needs to complete the eNVD registration process.
All calls to the new API must include the myMLA access token as a bearer token in the
authorization
header.Some GraphQL queries and mutations now require a new parameter (
envdAccountId
) to specify the account to perform the action under. Ensure that you include this parameter in the relevant API requests.
Refer to section 5 of this document to learn how to determine if a user is registered in the eNVD system.
5. User Registration and Management
This section covers the process of determining if a user is registered in the eNVD system, registering a user, and managing user accounts.
5.1 Determining if a User is Registered
query UserSignInQuery {
userDetailsQuery() {
data {
auth0Id
isNewUser
email
firstName
lastName
mobilePhone
defaultAccount
accounts {
envdAccountId
accountLabel
accountId
accountType
email
properties {
// Any LPA/NLIS/Transporter properties can be requested here.
// See the GraphQL playground for full schema
}
}
}
}
}
To determine if a user is registered in the eNVD system, follow these steps:
Call the
signIn
query, authenticated using the myMLA token. No need to specify any user parameters, as this is determined directly from the myMLA token.Check the value of the
isNewUser
field in the response:
- If
isNewUser
istrue
, the user is not registered in the eNVD system. - If
isNewUser
isfalse
, the user is registered in the eNVD system.
Example signIn
query:
Example response for an unregistered user:
{
"auth0Id": "1234abcd",
"isNewUser": true,
"email": "bobby@farm.com",
"firstName": "",
"lastName": "",
"mobilePhone": "",
"defaultAccount": "",
"accounts": [
{
"envdAccountId": "11223344",
"accountLabel": "QAZZ7777",
"accountId": "1234567",
"accountType": "LPA",
"email": "bobby@farm.com",
"properties": {}
}
]
}
Example response for a registered user:
{
"auth0Id": "1234abcd",
"isNewUser": false,
"email": "bobby@farm.com",
"firstName": "Bobby",
"lastName": "Smith",
"mobilePhone": "0404555666",
"defaultAccount": "envd-11223344",
"accounts": [
{
"envdAccountId": "11223344",
"accountLabel": "QAZZ7777",
"accountId": "1234567",
"accountType": "LPA",
"email": "bobby@farm.com",
"properties": {}
}
]
}
5.2 Registering a User in eNVD
To register a user in the eNVD system:
Direct the user to the new eNVD website or mobile application. Prompt the user to sign in with their myMLA account. If the user is not already registered, they will be automatically stepped through the eNVD registration process.
Note: Users who have previously used the eNVD mobile app or new eNVD website will already be registered.
5.3 Linking NLIS and LPA Accounts to myMLA
To link NLIS and LPA accounts to a myMLA user:
Direct the user to log into the myMLA dashboard. Instruct the user to navigate to the “linked services” menu. Guide the user to link their NLIS and LPA accounts.
Note: Linking NLIS and LPA accounts is not handled within the eNVD platform itself. It must be done through the myMLA dashboard.
6. Using the API
This section provides an overview of how to use the eNVD API, including GraphQL basics, authorisation, queries, mutations, and the envdAccountId
parameter.
6.1 GraphQL API Overview
The eNVD API is built using GraphQL, a query language for APIs that provides a flexible and efficient way to request and manipulate data. GraphQL allows you to define the structure of your data, specify the fields you need, and retrieve only the relevant information in a single request.
Key concepts in GraphQL:
- Schema: Defines the types, fields, and relationships of the data that can be queried and mutated.
- Queries: Used to fetch data from the API.
- Mutations: Used to modify data on the API.
- Variables: Allow you to pass dynamic values to queries and mutations.
To learn more about GraphQL and its concepts, refer to the official GraphQL documentation: https://graphql.org/learn/
6.2 authorisation Header and Bearer Token
authorisation: Bearer <ACCESS_TOKEN>
All requests to the eNVD API must include an authorisation header with a valid access token. The access token should be included as a bearer token in the authorization
header of the request.
Replace <ACCESS_TOKEN>
with the actual access token obtained through the OAuth 2.0 authorisation Code Flow (refer to section 3 for more details).
6.3 Queries and Mutations
Example query to retrieve a list of consignments:
query fetchConsignments($envdAccountId: String!, $first: Int, $after: String) {
consignments(envdAccountId: $envdAccountId, first: $first, after: $after) {
totalCount
pageInfo {
hasNextPage
endCursor
}
edges {
cursor
node {
id
number
status
# Include other fields as needed #
}
}
}
}
Example mutation to create a new consignment:
mutation createConsignment(
$envdAccountId: String!
$input: CreateOrSaveConsignmentInput!
) {
createOrSaveConsignment(envdAccountId: $envdAccountId, input: $input) {
data {
id
number
status
# Include other fields as needed #
}
}
}
The eNVD API provides a set of GraphQL queries and mutations to interact with the system. Queries are used to fetch data, while mutations are used to modify data.
For a complete list of available queries and mutations, refer to the eNVD API documentation or explore the GraphQL schema using the GraphQL playground (see section 6.5).
6.4 Using the envdAccountId
Parameter
query Consignments($envdAccountId: String!) {
consignments(envdAccountId: $envdAccountId) {
totalCount
#Include fields as needed#
}
}
With the introduction of the new user paradigm in the eNVD API, some queries and mutations now require an envdAccountId
parameter to specify the account under which the action should be performed. The envdAccountId
is mandatory for these operations.
To obtain the envdAccountId
, make a request to the userDetailsQuery
(refer to section 5.1 for an example). The envdAccountId
can be found in the accounts array of the response.
6.5 GraphQL Playground
The eNVD API provides a GraphQL playground, an interactive tool for exploring and testing the API. The playground allows you to browse the schema, execute queries and mutations, and view the responses. To access the GraphQL playground:
UAT/Staging environment: https://api.uat.integritysystems.com.au/v2/ui/playground
Use the playground to familiarize yourself with the available queries, mutations, and the structure of the GraphQL schema.
6.6 Consignments, Forms, Questions, and Answers
6.6.1 Consignment
A consignment represents a shipment or movement of livestock from one location to another. It contains all the relevant information about the livestock being transported, including the origin, destination, owner, consignee, and specific details about the animals.
6.6.2 Forms
Forms are associated with a consignment and represent different types of documents or declarations required for the movement of livestock.
Forms capture all the information related to the livestock within the consignment. The information captured on a form is determined by the program owner.
An eNVD user can only create a form for the programs they are accredited to (i.e. user must be both LPA and EU accredited to be able to create an EU vendor declaration).
All forms in the eNVD platform are identified with a unique Form ID. As new versions of forms are published, the form ID will also be updated to identify the change.
As of May 2024, the current form versions are:
Form ID | Program | Form Name | Species |
---|---|---|---|
LPAC1 | LPA | LPA National Vendor Declaration | Cattle |
EUC1 | LPA | LPA European Union National Vendor Declaration | Cattle |
LPABC1 | LPA | LPA National Vendor Declaration | Bobby Calves |
LPASL1 | LPA | LPA National Vendor Declaration | Sheep |
LPAG2 | LPA | LPA National Vendor Declaration | Goats |
NFASC0 | NFAS | NFAS Form B | Cattle |
NFASDDC1 | NFAS | NFAS Delivery Docket | Cattle |
NFASEUC1 | NFAS | NFAS Delivery Docket European Union Grain Fed High Quality Beef | Cattle |
MSAC1 | MSA | MSA Cattle Vendor Declaration | Cattle |
HSSL1 | National Sheep Health Declaration | Sheep | |
HSG0 | National Goat Health Declaration | Goats | |
HSC2 | National Cattle Health Declaration | Cattle |
6.6.3 Questions
Questions are the individual pieces of information that need to be collected for a consignment. They are defined in the GraphQL schema and have properties such as:
id
: A unique identifier for the question.order
: The order in which the question appears within the form.text
: The text or prompt of the question.readOnly
: Indicates whether the question is read-only or can be answered.forms
: The forms that the question relates to.type
: The data type of the answer expected for the question (e.g., “SINGLE_CHOICE”, “MULTIPLE_CHOICE”, “STRING”, “NUMBER”, etc.).triggers
: Conditions that determine when the question should be displayed based on the answers to other questions.validators
: Rules for validating the answer provided for the question.acceptableAnswers
: A list of predefined answers that can be selected for the question.childQuestions
: An array of sub-questions that are conditionally displayed based on the answer to the parent question.
6.6.4 Question IDs and Answers
When creating or updating a consignment, the answers to the questions are provided in the form of an answers
array. Each answer object contains the following properties:
questionId
: The ID of the question being answered.index
: The index of the answer if the question allows multiple answers (e.g., for “REPEATABLE” questions).value
: The actual answer value provided for the question.
The questionId
in the answers
array corresponds to the id
of the question defined in the GraphQL schema. This establishes the relationship between the questions and their respective answers within a consignment.
6.6.5 Child Questions
Child questions are sub-questions that are conditionally displayed based on the answer provided to a parent question. They follow the same structure as regular questions and can have their own triggers, validators, and acceptable answers. Child questions are defined within the childQuestions
array of a parent question.
6.6.6 Retrieving a list of Questions, Answers and Validators
{
query {
questions(envdAccountId: "880cafc7-3712-4bdf-59fb-08dc4de5d367") {
items {
id
order
text
readOnly
forms
type
triggers {
questionId
value
}
validators {
type
parameter
errorMessage
}
acceptableAnswers {
displayName
value
}
childQuestions {
id
order
text
readOnly
forms
type
triggers {
questionId
value
}
validators {
type
parameter
errorMessage
}
acceptableAnswers {
displayName
value
}
childQuestions {
id
order
text
readOnly
forms
type
triggers {
questionId
value
}
acceptableAnswers {
displayName
value
}
validators {
type
parameter
errorMessage
}
}
}
}
}
}
}
Here’s an example of how to obtain a list of questions and answers from the GraphQL API using a query:
In this query:
- We request various fields for each question, such as
id
,order
,text
,readOnly
,forms
,type
,triggers
,validators
,acceptableAnswers
, andchildQuestions
. - The
childQuestions
field is recursively queried to retrieve the nested child questions and their respective fields.
You can use this query to retrieve the list of questions and their details from the GraphQL API. The response can be used to dynamically generate forms, validate answers, and handle the logic of displaying child questions based on the answers provided.
Here’s an example response ):
{
"data": {
"questions": {
"items": [
{
"id": "1",
"order": 1,
"text": "Please provide a description of the livestock moving",
"readOnly": false,
"forms": [
"LPAC1",
"EUC1",
"LPABC1",
"LPASL1",
"LPAG2",
"NFASC0",
"NFASDDC1",
"NFASEUC1"
],
"type": "REPEATABLE",
"triggers": null,
"validators": [
{
"type": "required",
"parameter": "",
"errorMessage": "Required field"
}
],
"acceptableAnswers": [],
"childQuestions": [
{
"id": "2",
"order": 2,
"text": "Age (dentition)",
"readOnly": false,
"forms": ["NFASC0", "NFASDDC1", "NFASEUC1"],
"type": "SINGLE_CHOICE",
"triggers": null,
"validators": [],
"acceptableAnswers": [
{
"displayName": "0-2",
"value": "2"
},
{
"displayName": "0-4",
"value": "4"
}
// ...
],
"childQuestions": []
}
// ...
]
}
// ...
]
}
}
}
In this example response, we can see the structure of the questions and their associated details. Each question has an id
, order
, text
, readOnly
, forms
, type
, triggers
, validators
, acceptableAnswers
, and childQuestions
. The childQuestions
field contains an array of nested child questions that follow the same structure.
6.7 API Validation Rules and Errors
This section provides information about the inner validation rules and errors that can be triggered from the eNVD API.
6.7.1 Validation Errors
The eNVD API performs various validations on the input data and returns appropriate error responses when the validation rules are violated. The following table lists the common validation scenarios and their corresponding error responses:
{
"errors": [
{
"message": "The access token is invalid.",
"path": [
"createOrSaveConsignment"
],
"extensions": {
"data": {
"Code": "Unauthorized",
"Message": "The access token is invalid.",
"Description": null,
"OutcomeStatus": null
}
}
}
]
}
Invalid or expired token (Error)
{
"errors": [
{
"message": "Internal server error",
"path": [
"createOrSaveConsignment"
],
"extensions": {
"data": {
"Code": "",
"Message": "Internal server error",
"Description": null,
"OutcomeStatus": "ERROR"
}
}
}
]
}
Trying to update a non-existing consignment or if the user doesn’t have permission to the consignment (Error)
{
"errors": [
{
"message": "GraphQL.ExecutionError: Invalid type. Expected String but got Null.",
"path": [
"createOrSaveConsignment",
"species"
],
"extensions": {
"data": {
"Code": "species",
"Message": "Invalid type. Expected String but got Null.",
"Description": null,
"OutcomeStatus": "Error"
}
}
},
{
"message": "GraphQL.ExecutionError: Array item count 0 is less than minimum count of 1.",
"path": [
"createOrSaveConsignment",
"programs"
],
"extensions": {
"data": {
"Code": "programs",
"Message": "Array item count 0 is less than minimum count of 1.",
"Description": null,
"OutcomeStatus": "Error"
}
}
}
]
}
Empty forms in the payload (Error)
{
"errors": [
{
"message": "Variable '$input.forms[0]' is invalid. Unable to convert 'Form1' to 'EFormType'",
"locations": [
{
"line": 2,
"column": 3
}
],
"extensions": {
"code": "INVALID_VALUE",
"codes": [
"INVALID_VALUE",
"INVALID_OPERATION"
],
"number": "5.8"
}
}
]
}
Invalid form provided (Error)
{
"errors": [
{
"message": "Bad request",
"path": [
"createOrSaveConsignment"
],
"extensions": {
"data": {
"Code": "",
"Message": "Bad request",
"Description": "Programs 'Castle.Proxies.FormModelProxy,Castle.Proxies.FormModelProxy,Castle.Proxies.FormModelProxy,Castle.Proxies.FormModelProxy' linked to more than one species 'Cattle,Goat'",
"OutcomeStatus": "ERROR"
}
}
}
]
}
Mix different types of forms (Error)
{
"errors": [
{
"message": "'PIC1' is not a valid value for PIC.",
"path": [
"createOrSaveConsignment",
"<<Field Name>>"
],
"extensions": {
"data": {
"Code": "<<Field Name>>",
"Message": "'PIC1' is not a valid value for PIC.",
"Description": null,
"OutcomeStatus": "Error"
}
}
}
]
}
Invalid PIC in any of the PIC-related fields (Error)
{
"errors": [
{
"message": "'MIHA0548' is not associated with user.",
"path": [
"createOrSaveConsignment",
"consignorPic"
],
"extensions": {
"data": {
"Code": "consignorPic",
"Message": "'MIHA0548' is not associated with user.",
"Description": null,
"OutcomeStatus": "Error"
}
}
}
]
}
Source/Origin PIC is different from the selected LPA account (Error)
{
"errors": [
{
"message": "GraphQL.ExecutionError: Required",
"path": [
"createOrSaveConsignment",
"otherHealthInformation",
"negativeHerdTestDetails",
"lastTestDate"
],
"extensions": {
"data": {
"Code": "otherHealthInformation.negativeHerdTestDetails.lastTestDate",
"Message": "Required",
"Description": null,
"OutcomeStatus": "Error"
}
}
}
]
}
Required answers not provided in the payload (Warning)
{
"errors": [
{
"message": "GraphQL.ExecutionError: Question 113: 2024-09-06 is not valid.",
"path": [
"createOrSaveConsignment"
],
"extensions": {
"data": {
"Code": "otherHealthInformation.negativeHerdTestDetails.lastTestDate",
"Message": "Question 113: 2024-09-06 is not valid.",
"Description": "",
"OutcomeStatus": "Error"
}
}
}
]
}
Invalid data provided in the answer (Warning)
6.7.2 Field-level Validation and Dependencies
To retrieve the field-level validation rules and dependencies, you can run the GraphQL query provided in section 6.6.6
6.7.3 Validators
"validators": [
{
"type": "minYear",
"parameter": "1900",
"errorMessage": "Minimum year of 1900"
},
{
"type": "maxYear",
"parameter": "now",
"errorMessage": "Date cannot be in the future"
}
]
The validators field contains the validation rules for a question, such as the maximum supported value, minimum value, length of a string, etc. The errorMessage field provides the corresponding error message if the validation rules are not met. Example:
6.7.4 Acceptable answers
"acceptableAnswers": [
{
"displayName": "Feed standard not met",
"value": "0"
},
{
"displayName": "GFF - 35 days or more",
"value": "35"
},
{
"displayName": "GFYG - 60 days or more (heifers only)",
"value": "60"
},
{
"displayName": "GFYG - 70 days or more",
"value": "70"
},
{
"displayName": "GF - 100 days or more",
"value": "100"
}
]
The acceptableAnswers field contains the acceptable answers for “Single Choice” and “Multiple Choice” questions. Example:
{
"message": "Answer: abc is not valid. Acceptable answers are: 0,35,60,70,100",
"path": ["createOrSaveConsignment"],
"extensions": {
"data": {
"Code": "declaration.declarePartIV.fedNotLessThan[]",
"Message": "Answer: abc is not valid. Acceptable answers are: 0,35,60,70,100",
"Description": "",
"OutcomeStatus": "Error"
}
}
}
Violating these rules will result in the following error:
6.7.4 Conditional Validation
{
"id": "57",
"text": "Give details",
"acceptableAnswers": [],
"type": "STRING",
"triggers": [
{
"questionId": "56",
"value": "Yes"
}
]
}
Some validations are triggered by the value of another field. These conditional validations can be found in the triggers field. In the example below, the validation rules for question “57” will be applied if the answer to question “56” is “Yes”.
6.7.5 Other Validation
{
"input": {
"forms": ["LPAC1", "NFASDDC1", "MSAC1", "HSC2"],
"origin": {
"address": {
"line1": "North Sydney",
"postcode": "2060",
"state": "NSW",
"town": "North Sydney"
},
"name": "ISC test account",
"pic": "QDZZ3333"
},
"destination": {
"address": {
"line1": "",
"state": "NSW",
"town": "EAST KURRAJONG"
},
"name": "MD & VM JONES",
"pic": "NI462324"
},
"owner": {
"address": {
"line1": "North Sydney",
"postcode": "2060",
"state": "NSW",
"town": "North Sydney"
},
"name": "ISC test account",
"pic": "QDZZ3333"
},
"consignee": {
"address": {
"line1": "",
"state": "NSW",
"town": "EAST KURRAJONG"
},
"name": "MD & VM JONES",
"pic": "NK992233"
},
"declaration": {
"accept": false,
"address": {
"line1": "1/40 MOUNT ST",
"postcode": "2060",
"state": "NSW",
"town": "NORTH SYDNEY"
},
"certificateNumber": null,
"date": "2023-12-15T00:00:00",
"email": null,
"fullName": "ISC Test Account",
"phone": null,
"signature": null
},
"movementDate": "2022-12-19",
"movementTime": null,
"status": "DRAFT",
"answers": []
}
}
In addition to the field-level validation for questions, the eNVD API also performs validation on other consignment-level fields that are not exposed through the questions
query. These fields are part of the input
object when creating or updating a consignment.
Here’s a sample request payload:
The following table describes the validation rules for these consignment-level fields:
Field | Mandatory | Type | Validation |
---|---|---|---|
forms | Yes | String Array | Accepts only the following values: EUC1, HSC2, HSG0, HSSL1, LPABC1, LPAC1, LPAG2, LPASL1, MSAC1, NFASC0, NFASDDC1, NFASEUC1 |
origin.address.line1, destination.address.line1, owner.address.line1, consignee.address.line1, declaration.address.line1 | No | String | Max Length: 300 characters |
origin.address.postcode, destination.address.postcode, owner.address.postcode, consignee.address.postcode, declaration.address.postcode | No | Numeric String | Length: 4, Max: 9999, Min: 1000 |
origin.address.state, destination.address.state, owner.address.state, consignee.address.state, declaration.address.state | No | String | Accepts only the following values: “ACT”, “NSW”, “NT”, “QLD”, “SA”, “TAS”, “VIC”, “WA” |
origin.address.town, destination.address.town, owner.address.town, consignee.address.town, declaration.address.town | No | String | Max Length: 100 characters |
origin.name, destination.name, owner.name, consignee.name | No | String | Max Length: 300 characters |
origin.pic, destination.pic | Yes | String | Accepts only valid PIC format |
owner.pic, consignee.pic | No | String | Accepts only valid PIC format |
declaration.accept | No | Boolean | - |
declaration.certificateNumber | No | String | Max Length: 7 characters |
declaration.date | No | DateTime | Valid Date format |
declaration.email | No | String | Valid email address |
declaration.fullName | No | String | Max Length: 300 characters |
declaration.phone | No | String | A valid phone number (e.g., 0299999999 or +61400000000) |
declaration.signature | No | String | Base64 version of the signature image |
movementDate | No | Date | Valid date in ISO-8601 format (yyyy-MM-dd) |
movementTime | No | 24 hr time format | Example: “17:40” |
status | No | String | Accepts only the following values: DELETED, DRAFT, SUBMITTED, LOCKED |
Ensure that the input data for these consignment-level fields conforms to the specified validation rules to avoid validation errors when creating or updating a consignment using the eNVD API.
By understanding the validation rules, accepted answers, and conditional validations, you can ensure that the data sent to the eNVD API meets the required criteria and handle any validation errors appropriately in your application.
7. User Roles and Responsibilities
The eNVD API introduces a new concept of user roles, which determine the level of access and permissions a user has within the system. This section explains the different user roles and their associated privileges.
7.1 User Roles
The eNVD API defines the following user roles:
- Producer (legacy): PIC-based accounts responsible for creating and maintaining consignment records. They have the highest level of privileges.
- Receiver: PIC-based accounts that can access and manage consignments where they are the receiver of the livestock or the destination address.
- Facilitator: PIC-based accounts that assist with management duties and enabling buyer accounts to access consignment records.
- Transporter: Email-based accounts that are granted access to view consignments. They are typically assigned to by a Producer role, but a transporter assigned to a consignment can also add other transporters.
- Buyer: PIC or email-based accounts that are granted access to view consignments they have bought via a saleyard. Buyers are specifically assigned to consignments by a Facilitator role, along with details about the number of purchased heads.
- Authenticated Viewer: Email-based accounts that are granted read-only access to consignments they are specifically assigned to by a Producer role.
7.2 Role-based Access and Permissions
Each user role has specific access rights and permissions within the eNVD system:
Producer (LPA accounts):
Authentication:
- Must have a valid LPA accreditation
- Authenticated through myMLA login
Features and Permissions:
- Can create new consignments associated with their PIC(s)
- Can view, update, and delete consignments they have created
- Can submit consignments for processing
- Can add or update transporter details on their consignments
- Can add or remove authenticated viewers on their consignments
- Can grant access to buyers for specific consignments
- Can view and manage all consignments associated with their PIC(s), including those created by other users with access to the same PIC(s)
- Can add and view comments on associated consignments
Receiver (LPA or NLIS PIC-based accounts):
Authentication:
- Must have a valid PIC associated with their account
- Authenticated through myMLA login
Features and Permissions:
- Can view consignments where their PIC is listed as the destination or receiver
- Can update specific details on consignments where they are the receiver, such as arrival date and time, and number of head received
- Cannot create new consignments or modify other aspects of the consignment
- Can add and view comments on associated consignments
Facilitator (NLIS saleyard or agent PIC-based accounts):
Authentication:
- Must have a valid PIC associated with their account
- Authenticated through myMLA login
Features and Permissions:
- Can view consignments associated with their PIC(s)
- Can add or remove buyers on consignments associated with their PIC(s)
- Can manage access permissions for buyers on specific consignments
- Cannot create, update, or delete consignments directly
- Can add and view comments on associated consignments
Transporter (email-based accounts):
Authentication:
- Must have a valid email address associated with their account
- Authenticated through myMLA login
Features and Permissions:
- Can view consignments they have been assigned to by a producer
- Can update specific transport details on assigned consignments, such as pickup date and time, vehicle registration, and driver information
- Can add other transporters to a consignment they’re assocaited with
- Cannot create new consignments or modify other aspects of the consignment
- Can add and view comments on associated consignments
Buyer (email-based accounts):
Authentication:
- Must have a valid email address associated with their account
- Authenticated through myMLA login
Features and Permissions:
- Can view consignments they have been granted access to by a facilitator or producer
- Can see specific details related to the purchased livestock, such as number of head, breed, and sex
- Cannot create, update, or delete consignments
- Cannot modify other aspects of the consignment
- Cannot add or view comments on associated consignments
Authenticated Viewer (email-based accounts):
Authentication:
- Must have a valid email address associated with their account
- Authenticated through myMLA login
Features and Permissions:
- Can view consignments they have been granted access to by a producer
- Cannot create, update, or delete consignments
- Cannot modify any aspects of the consignment
- Read-only access to the consignment details
- Can add and view comments on associated consignments
7.3 authorisation Errors and Handling
The eNVD API enforces role-based access control to ensure that users can only perform actions they are authorised to do. If a user tries to access a resource or perform an action they don’t have permission for, the API will respond with a 403 Unauthorized
error.
Example scenarios that would result in a 403 Unauthorized
error:
- A Producer tries to create a consignment for a PIC they don’t have rights to.
- A non-PIC based role (e.g., Transporter) tries to create a consignment.
- A user tries to access a consignment they are not assigned to.
When handling API responses, check for the presence of a 403 Unauthorized error
and handle it appropriately in your application, such as displaying an error message to the user or redirecting them to a different page.
8. API Reference
This section provides a reference of the available queries and mutations in the eNVD API, along with brief descriptions and links to more detailed documentation.
8.1 Queries
consignments
: Retrieves a list of consignments based on various filter criteria.
consignment
: Retrieves a specific consignment by its ID and account ID.
templates
: Retrieves a list of templates based on various filter criteria.
template
: Retrieves a specific template by its ID and account ID.
userDetails
: Retrieves details about the authenticated user, including their account information.
consignmentUserMapping
: Retrieves consignment user mappings based on account ID, consignment number, and role.
edecs
: Retrieves a list eDECs created by the user via the eDEC system
questions
: Retrieves a list of all questions
configurations
: Retrieves a list of all dynamic configurations
comments
: Retrieves a list of comments for a consignment
For a complete list of available queries and their parameters, refer to section 9 - code examples
8.2 Mutations
createOrSaveConsignment
: Creates or updates a consignment.
deleteConsignment
: Deletes a consignment.
createOrSaveTemplate
: Creates or updates a template.
deleteTemplate
: Deletes a template.
copyConsignment
: Creates a copy of a consignment previously created by the producer.
createOrSaveUser
: Creates or updates a user.
createComment
: Creates a comment for a consignment.
For a complete list of available mutations and their parameters, refer to section 9 - code examples
9. Code Examples
This section provides code examples for common tasks in the eNVD API, such as retrieving consignments, creating a consignment, and viewing user details.
9.1 Retrieving User Details
9.2 Retrieving Consignments
9.3 Creating a Consignment
9.4 Updating a Consignment
9.5 Submitting a Consignment
9.6 Deleting a Consignment
9.7 Add a Transporter to a Consignment
9.8 Add a Viewer to a Consignment
9.9 Retrieving a viewer
9.10 Add a Comment to a Consignment
9.11 Retrieving Comments
9.12 Creating a Template
9.13 Retrieving Templates
9.14 Creating from a Template
9.15 Copying a Consignment
10. Best Practices and Tips
This section provides best practices and tips for working with the eNVD API efficiently and effectively.
10.1 Performance Optimization
Use pagination and filtering options provided by the API to retrieve only the necessary data. Avoid fetching large datasets unnecessarily. Implement caching mechanisms in your application to store and reuse frequently accessed data, reducing the number of API requests and improving performance.
10.2 Pagination and Filtering
- Utilize the pagination parameters (
first
,after
) in queries to retrieve data in smaller chunks and iterate through the results. - Take advantage of the available filtering options, such as
searchText
,fromDate
,toDate
,status
, andspecies
, to narrow down the result set and retrieve specific data.
10.3 Error Handling and Troubleshooting
- Handle common error scenarios gracefully in your application, such as displaying user-friendly error messages for
400 Bad Request
,401 Unauthorized
, and403 Forbidden errors
. - Log and monitor API errors and exceptions for troubleshooting and debugging purposes.
- Consult the eNVD API error documentation for guidance on handling specific error codes and messages.
10.4 Security Considerations
- Keep your API credentials (client ID) secure and do not expose them in client-side code or version control systems.
- Use secure communication protocols (HTTPS) for all API requests to protect sensitive data.
- Implement proper access controls and authentication mechanisms in your application to ensure that only authorised users can access the API and perform actions.
11. Updates and New Features
11.1 Harvested Rangeland Goat (HRG) Form
Effective Date: October 1, 2024
A new form type, the Harvested Rangeland Goat (HRG) form, will be added to the eNVD system. This section outlines the key details for integrators to incorporate this new form into their applications.
What are Harvested Rangeland Goats?
Harvested Rangeland Goats (HRGs) are feral or semi-feral goats that are not traditionally farmed but are instead harvested from wild or semi-wild populations with minimal human intervention. HRGs play a significant role in Australia’s goat meat export industry. They are subject to specific National Livestock Identification System (NLIS) regulations, which allow them to be moved without individual identification devices under certain conditions. This exemption is due to the challenges of tagging animals in extensive rangeland environments while maintaining traceability and biosecurity standards. The HRG eNVD specifically addresses whether goats in a consignment meet the NLIS Standards’ definition of HRGs and are eligible for device-free movement.
Form Code
When creating an HRG form, use the following From ID:
LPAHRG0
Accreditation Requirement
The HRG form is accreditation-driven. Only users with the appropriate HRG accreditation flag on their LPA profile will be able to create and view this form. Integrators should check for the hRG
field in the user details query response to determine if a user has HRG accreditation:
query userDetailsQuery {
userDetails {
firstName
lastName
email
accounts {
envdAccountId
}
accreditations {
lPA
eU
mSA
eUGFHQB
nFAS
hRG
}
}
roles
}
}
}
If hRG
is true, the user has HRG accreditation.
New Question
The HRG form introduces one new question:
- Question ID: 185
- Question Text: “Do all goats in this consignment meet the Harvested Rangeland Goat definition as per the NLIS Standards for Goats and are eligible to be moved device free?”
- Type: Yes/No question
- Possible Answers: Yes, No
- Help text: Confirm that all goats in the consignment meet the Harvested Rangeland Goat definition. If all goats in the consignment do not meet the Harvested Rangeland Goat definition they are not eligible to move on a LPA HRG NVD. Ineligible goats must be NLIS identified and moved on an LPA NVD for Goats.
Important Note: If the answer is “No”, there’s a critical warning message: “IF NO - The Goats are not eligible to be moved device free on this NVD/Waybill and you are not adhering to your LPA Accreditation. You risk removal from the LPA Program and access to abattoirs and Registered Goat Depots that process Harvested Rangeland Goats.”
Note that although Question ID 185 supports both Yes and No values, only Yes will result in a consignment being created.
Sample Code for Creating an HRG Form
Here’s an example of how to create an HRG form using the eNVD API:
mutation createOrSaveConsignmentMutation(
$input: CreateOrSaveConsignmentInput!
$envdAccountId: String!
) {
createOrSaveConsignment(input: $input, envdAccountId: $envdAccountId) {
data {
id
number
status
// Include other fields as needed
}
}
}
Variables:
{
"input": {
"forms": ["LPAHRG0"],
"origin": {
// Origin details...
},
"destination": {
// Destination details...
},
"owner": {
// Owner details...
},
"consignee": {
// Consignee details...
},
"movementDate": "2024-10-15",
"answers": [
{
"questionId": "185",
"index": null,
"value": "Yes"
}
// Include other required answers...
],
"declaration": {
// Declaration details...
}
},
"envdAccountId": "your_envd_account_id_here"
}
Important Considerations
- The HRG form functionality is only available on the V2 APIs.
- The HRG form will only be available to users with the HRG accreditation set within their LPA profile
- The new question (ID: 185) replaces an existing question from the standard goat NVD regarding device-free or tag-free animals.
- Integrators must ensure that all fields in the form are accurately completed, similar to other forms.
When implementing Question 185:
- Ensure it’s prominently displayed for HRG forms.
- Implement clear yes/no radio buttons or a similar selection mechanism.
- If “No” is selected, display the warning message prominently to the user.
For any questions or issues related to the new HRG form, please contact our support team.
NLIS
About NLIS
The National Livestock Identification System (NLIS) is Australia’s system for the identification and traceability of cattle, sheep and goats. NLIS reflects Australia’s commitment to biosecurity and food safety and provides a competitive advantage in a global market.
As animals are bought, sold and moved along the supply chain, they must be tagged with an NLIS accredited tag or device from their property (PIC) of birth. In most cases this tag will remain with the animal for their entire life and it is illegal to remove this tag.
If tags are lost or become defective then a new tag can be applied, however if the animal is no longer at its place of birth then a ‘post breeder’ tag must be used. This indicates that the animal no longer has ‘lifetime’ traceability.
All animals leaving a PIC must be identified with an NLIS accredited device before moving, unless a permit is obtained from the state or territory. Each movement they make to a location with a different PIC must be recorded centrally on the NLIS database by people with NLIS accounts. NLIS accounts are free to open and operate.
Using this information, the NLIS is able to provide a life history of an animal’s movements and discern if contact with other livestock occurred. The NLIS is required to facilitate the traceability of animals in accordance with the National Traceability and Performance Standards.
About the NLIS API
The purpose of the NLIS SOAP API is to define how third-party systems can communicate with the NLIS Database:
- to retrieve information from the database, and/or
- to update information on the database.
For the majority of users, the NLIS Database website (www.nlis.mla.com.au) will provide the primary mechanism for interacting with the database: for submitting updates to data, and for requesting data from NLIS. The NLIS SOAP interface specifications details those enquiry/update processes that can be initiated/integrated from outside that website. It provides all the information required for third-party software vendors/developers to integrate their systems with the NLIS Database.
For example:
- a cattle management software package can update the database whenever any of the cattle it lists are sold or killed.
- an abattoir management package can automatically retrieve the ERP status of cattle it is about to process.
All the processes detailed in the NLIS SOAP interface specifications are provided to approved users of the NLIS Database, via direct user interaction. This document simply details alternative, programmable methods for obtaining the same results.
NLIS API Documentation
For further information about the NLIS API contact the ISC Integration Analyst at:
developersupport@integritysystems.com.au
ISC environments
Status Codes
Status Code | Meaning |
---|---|
200 | Ok – The default success code for requests that return a valid response in the response body, even if the response does not contain any rows or pagination. When POST-ing a new record a 200 indicates that while the request was correctly processed the record may not have been accepted, the body of the Response will indicate the reason for this error. |
201 | Created – Success code for a POST request for a collection, indicating the record was successfully created. Note: While a 201 indicates the record was recorded, there may be Informational or Warning messages (in the Response body) that may require some corrective action to occur. |
304 | Not Modified – The request content has not changed since a specified date and time (provided in an If-Modified-Since parameter in the request). |
400 | Bad Request – The data passed in the request could not be understood, or translated to into an internal format. Typically, the passed message fails simple type validation rules (e.g. passing a string when a number is expected), or document structure rules (e.g. is a malformed XML or JSON document). |
401 | Unauthorized – This error is returned when the OAuth token used has expired or is invalid; the user attempts to perform an action for which they are not authorized; or if a login attempt fails due to bad credentials. |
403 | Forbidden – Authentication was provided, but the authenticated user is not permitted to perform the requested operation. |
404 | Not Found – The requested resource could not be found. This error is generally returned when an entity with a specific ID is not found in our database. Check the URI for correct format, and that any IDs passed in the URI are valid. |
500 | Internal Server Error – Any internal server error that was not explicitly trapped by the application. An error has occurred within the platform, or the system is not compatible with the NLIS API, so the request could not be completed. Contact the NLIS Development Team at technicalsupport@IntegritySystems.com.au for assistance with this error. |
503 | Service Unavailable – We’re temporarially offline for maintanance. Please try again later. |