Tutorial: Your first iGUIDE
Learn how to create an iGUIDE, upload Stitch Data and check processing status using the Portal API.
Time to complete: ~10 minutes
What you'll learn:
- How to authenticate with the Portal API
- How to create a new iGUIDE
- How to upload Stitch Data to S3
- How to poll for processing completion
Prerequisites
Before you begin, you need:
- App ID and Access Token (see below for how to create them)
- A Stitch TAR file (for this tutorial, we'll assume you have
property.stitch.tar) - curl or any HTTP client
Getting your API credentials
You can self-serve your API credentials via the API Management page in the iGUIDE Portal:
- Log in to the iGUIDE Portal
- Navigate to Settings → API Management
- Click Create API Token
- Provide a name and select the required scopes (for this tutorial, you'll need
iguide.tasksandiguide.rw) - Copy the Token ID (this is your
$APP_ID) and Token Value (this is your$APP_TOKEN)
The token value is only shown once when created. Make sure to save it securely—you won't be able to retrieve it later. If you lose it, you'll need to rotate or create a new token.
For getting started quickly, we recommend using API Tokens as shown above. They're simpler and faster to set up.
If you need full OAuth 2.0 authentication with authorization flows, you can create an OAuth App instead. See our Authentication Guide for complete details on both methods.
Step 1: Set up your environment
First, let's store your credentials as environment variables for easy reuse:
export APP_ID="your-app-id-here"
export APP_TOKEN="your-access-token-here"
All Portal API requests require these two authentication headers:
X-Plntr-App-Id: Your application UUIDX-Plntr-App-Token: Your JWT access token
Step 2: Test your authentication
Before creating an iGUIDE, verify your credentials are working:
curl -X POST https://youriguide.com/api/v1/integrations/test \
-H "X-Plntr-App-Id: $APP_ID" \
-H "X-Plntr-App-Token: $APP_TOKEN"
Expected response:
{
"appId": "your-app-id-here"
}
If you receive a 401 Unauthorized error, double-check your credentials.
Step 3: Create your first iGUIDE
Now let's create a new iGUIDE. You need to provide three required fields:
type: The iGUIDE package type (e.g.,"standard","premium","radix")industry: The property type (e.g.,"residential","commercial")address: Complete property address
curl -X POST https://youriguide.com/api/v1/iguides \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "X-Plntr-App-Id: $APP_ID" \
-H "X-Plntr-App-Token: $APP_TOKEN" \
-d '{
"type": "standard",
"industry": "residential",
"address": {
"country": "CA",
"provinceState": "ON",
"city": "Waterloo",
"postalCode": "N2L 3G1",
"streetName": "University Ave",
"streetNumber": "200"
}
}'
Response:
{
"id": "ig12345",
"alias": "200_university_ave_waterloo_on",
"workOrderId": "Z1T9",
"defaultViewId": "v123"
}
Important: Save the id and workOrderId from this response—you'll need them for uploading data.
export IGUIDE_ID="ig12345"
export WORK_ORDER_ID="Z1T9"
What just happened?
- An iGUIDE was created with a unique ID (
ig12345) - A work order was automatically created to track processing (
Z1T9) - A default view was created for displaying the final iGUIDE (
v123) - An alias was generated from the address for friendly URLs
Step 4: Get S3 upload credentials
To upload your Stitch Data, you need temporary AWS credentials. The Portal API uses STS federation tokens (not presigned URLs) that are valid for 24 hours.
curl -X POST https://youriguide.com/api/v1/iguides/$IGUIDE_ID/workOrders/$WORK_ORDER_ID/stitchData \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "X-Plntr-App-Id: $APP_ID" \
-H "X-Plntr-App-Token: $APP_TOKEN" \
-d '{
"filename": "property.stitch.tar",
"filesize": 55395840
}'
The filesize value must be the exact size of the file in bytes. Use stat filename.tar to get it.
Response:
{
"id": "4MN",
"uploadPermit": {
"region": "us-east-1",
"bucket": "iguides.plntr.ca",
"key": "stitch-data/4MN/original.tar",
"accessKeyId": "ASIAXXX...",
"secretAccessKey": "xxx...",
"sessionToken": "FwoGZXIvYXdz..."
},
"uploadToken": "eyJhbGciOiJIUzI1NiIs..."
}
These temporary credentials expire after 24 hours. If your upload takes longer, request new credentials. For a deep dive on this pattern, see S3 Upload Pattern.
Step 5: Upload to S3
Now use the AWS credentials to upload your Stitch TAR file directly to S3:
# Save the credentials from the upload permit response
export AWS_ACCESS_KEY_ID="ASIAXXX..."
export AWS_SECRET_ACCESS_KEY="xxx..."
export AWS_SESSION_TOKEN="FwoGZXIvYXdz..."
export S3_BUCKET="iguides.plntr.ca"
export S3_KEY="stitch-data/4MN/original.tar"
export STITCH_DATA_ID="4MN"
export UPLOAD_TOKEN="eyJhbGciOiJIUzI1NiIs..."
# Upload using AWS CLI
aws s3 cp property.stitch.tar s3://$S3_BUCKET/$S3_KEY \
--acl bucket-owner-full-control \
--region us-east-1
For production applications, use an official AWS SDK (JavaScript, Python, Go, etc.) to handle S3 uploads. The SDKs handle authentication, retries and multipart uploads automatically. See S3 Upload Pattern for examples in multiple languages.
Expected output:
upload: ./property.stitch.tar to s3://iguides.plntr.ca/stitch-data/$STITCH_DATA_ID/original.tar
Step 6: Trigger processing
After uploading to S3, tell the Portal API to process the uploaded file. Pass the stitchDataId in the path and the uploadToken as a query parameter:
curl -X POST "https://youriguide.com/api/v1/iguides/$IGUIDE_ID/workOrders/$WORK_ORDER_ID/stitchData/$STITCH_DATA_ID/process?uploadToken=$UPLOAD_TOKEN" \
-H "X-Plntr-App-Id: $APP_ID" \
-H "X-Plntr-App-Token: $APP_TOKEN"
Response:
{
"jid": "abc123",
"jidEnqueuedAt": "2025-02-18T19:30:00Z"
}
This enqueues an asynchronous processing job. The iGUIDE processing pipeline typically takes 15-30 minutes depending on the size and complexity.
The stitchDataId is found in the output of the S3 upload.
Step 7: Poll for completion
To check if your iGUIDE is ready, poll the work order status:
curl https://youriguide.com/api/v1/iguides/$IGUIDE_ID/workOrders/$WORK_ORDER_ID \
-H "X-Plntr-App-Id: $APP_ID" \
-H "X-Plntr-App-Token: $APP_TOKEN"
Response (processing):
{
"id": "Z1T9",
"status": "pending_draft",
"iguideId": "ig12345",
"iguideType": "standard"
}
Response (completed):
{
"id": "Z1T9",
"status": "done",
"iguideId": "ig12345",
"iguideType": "standard"
}
Work order status values:
empty: Initial state, no data uploaded yetpending_draft,pending_qa,pending_publish,exception: Work order is being processedon_hold: Queued behind another active work orderdone: iGUIDE is ready to viewcancelled: Work order was cancelledrejected: Processing rejected due to data quality issues
Step 8: Access your iGUIDE
Once the work order status is done, your iGUIDE is ready! You can:
View in the Portal:
https://manage.youriguide.com/iguides/edit/ig12345
Embed in your application:
<iframe src="https://my.youriguide.com/v123" width="100%" height="600px"></iframe>
Download deliverables:
- Floor plans (DWG, RVT)
- Measurement data (ESX)
- Check the API Reference for download endpoints
Complete script
Here's the complete workflow in a single script:
#!/bin/bash
set -e
# Configuration
export APP_ID="your-app-id"
export APP_TOKEN="your-access-token"
STITCH_FILE="property.stitch.tar"
# 1. Test authentication
echo "Testing authentication..."
curl -X POST https://youriguide.com/api/v1/integrations/test \
-H "X-Plntr-App-Id: $APP_ID" \
-H "X-Plntr-App-Token: $APP_TOKEN"
# 2. Create iGUIDE
echo "Creating iGUIDE..."
CREATE_RESPONSE=$(curl -s -X POST https://youriguide.com/api/v1/iguides \
-H "Content-Type: application/json" \
-H "X-Plntr-App-Id: $APP_ID" \
-H "X-Plntr-App-Token: $APP_TOKEN" \
-d '{
"type": "standard",
"industry": "residential",
"address": {
"country": "CA",
"provinceState": "ON",
"city": "Waterloo",
"postalCode": "N2L 3G1",
"streetName": "University Ave",
"streetNumber": "200"
}
}')
IGUIDE_ID=$(echo $CREATE_RESPONSE | jq -r '.id')
WORK_ORDER_ID=$(echo $CREATE_RESPONSE | jq -r '.workOrderId')
echo "Created iGUIDE: $IGUIDE_ID with Work Order: $WORK_ORDER_ID"
# 3. Get upload permit
echo "Getting S3 upload credentials..."
UPLOAD_RESPONSE=$(curl -s -X POST https://youriguide.com/api/v1/iguides/$IGUIDE_ID/workOrders/$WORK_ORDER_ID/stitchData \
-H "Content-Type: application/json" \
-H "X-Plntr-App-Id: $APP_ID" \
-H "X-Plntr-App-Token: $APP_TOKEN" \
-d "{
\"filename\": \"$STITCH_FILE\",
\"filesize\": $(stat -c%s "$STITCH_FILE")
}")
STITCH_DATA_ID=$(echo $UPLOAD_RESPONSE | jq -r '.id')
UPLOAD_TOKEN=$(echo $UPLOAD_RESPONSE | jq -r '.uploadToken')
export AWS_ACCESS_KEY_ID=$(echo $UPLOAD_RESPONSE | jq -r '.uploadPermit.accessKeyId')
export AWS_SECRET_ACCESS_KEY=$(echo $UPLOAD_RESPONSE | jq -r '.uploadPermit.secretAccessKey')
export AWS_SESSION_TOKEN=$(echo $UPLOAD_RESPONSE | jq -r '.uploadPermit.sessionToken')
S3_BUCKET=$(echo $UPLOAD_RESPONSE | jq -r '.uploadPermit.bucket')
S3_KEY=$(echo $UPLOAD_RESPONSE | jq -r '.uploadPermit.key')
# 4. Upload to S3
echo "Uploading to S3..."
aws s3 cp $STITCH_FILE s3://$S3_BUCKET/$S3_KEY \
--acl bucket-owner-full-control \
--region us-east-1
# 5. Trigger processing
echo "Triggering processing..."
curl -s -X POST "https://youriguide.com/api/v1/iguides/$IGUIDE_ID/workOrders/$WORK_ORDER_ID/stitchData/$STITCH_DATA_ID/process?uploadToken=$UPLOAD_TOKEN" \
-H "X-Plntr-App-Id: $APP_ID" \
-H "X-Plntr-App-Token: $APP_TOKEN"
# 6. Poll for completion
echo "Polling for completion..."
while true; do
STATUS_RESPONSE=$(curl -s https://youriguide.com/api/v1/iguides/$IGUIDE_ID/workOrders/$WORK_ORDER_ID \
-H "X-Plntr-App-Id: $APP_ID" \
-H "X-Plntr-App-Token: $APP_TOKEN")
STATUS=$(echo $STATUS_RESPONSE | jq -r '.status')
echo "Current status: $STATUS"
if [ "$STATUS" = "done" ]; then
echo "iGUIDE is ready! View at: https://youriguide.com/iguides/$IGUIDE_ID"
break
elif [ "$STATUS" = "rejected" ] || [ "$STATUS" = "cancelled" ]; then
echo "Processing $STATUS!"
exit 1
fi
sleep 30
done
Next steps
Congratulations! You've successfully created your first iGUIDE using the Portal API. Here's what to explore next:
- S3 Upload Pattern—Deep dive on uploads, multipart, error handling and SDK examples
- Work Order Lifecycle—Understand all work order statuses and transitions
- Webhooks—Get real-time notifications instead of polling
- API Reference—Explore all available endpoints
Troubleshooting
Authentication fails (401)
Problem: {"code": "unauthenticated"}
Solutions:
- Verify your App ID and Access Token are correct
- Check for extra whitespace in your credentials
- Ensure headers use exact names:
X-Plntr-App-IdandX-Plntr-App-Token
iGUIDE creation fails (400)
Problem: {"code": "invalid_argument"}
Solutions:
- Verify all required fields are provided:
type,industry,address - Check that the address is complete and valid
- Ensure
typeis one of:standard,premium,radix,photos - Ensure
industryis one of:residential,commercial,irc,aec
S3 upload fails (403)
Problem: Access Denied when uploading to S3
Solutions:
- Verify you're using all three credentials:
accessKeyId,secretAccessKeyandsessionToken - Ensure you're including
--acl bucket-owner-full-controlon the upload - Check if credentials expired (24-hour lifetime for Stitch Data)
- Ensure you're uploading to the exact bucket and key from the
uploadPermitresponse - Request new credentials if needed
Work order stays in processing
Problem: Status remains in a processing state (pending_draft, pending_qa, etc.) for longer than expected.
Solutions:
- Check the file was uploaded correctly to S3
- Verify you called the
/processendpoint after uploading - Contact support if the issue persists—there may be a processing error
Rate limiting (429)
Problem: {"code": "resource_exhausted"}
Solutions:
- Check the
X-RateLimit-*response headers for your current limits - Reduce request frequency
- Wait for the
Retry-Afterduration before retrying - Consider using webhooks instead of aggressive polling