Skip to main content

Searching Files Attached to Records

Learn how to search for files attached to transactions (purchase orders, invoices, etc.) using the SOAP Advanced Search with file join.

Prerequisites

  • NetSuite connector configured with soap resource enabled
  • Transaction internal ID

Why Use This Action?

Files attached to transactions via the SOAP attach operation cannot be queried using SuiteQL. The search_transaction_files action uses SOAP Advanced Search with fileJoin to retrieve these attachments.

Basic Usage

from abstra.connectors import run_connection_action

# Search for files attached to a purchase order
result = run_connection_action(
"netsuite",
"search_transaction_files",
{
"transactionId": "670932",
"transactionType": "purchaseOrder"
}
)

# Check results
if result['status'] == 'success':
files = result['data']['files']
print(f"Found {len(files)} attached files")

for file in files:
print(f" - {file['fileName']} (ID: {file['fileId']})")
print(f" Type: {file['fileType']}")
print(f" URL: {file['fileUrl']}")

Parameters

ParameterTypeRequiredDescription
transactionIdstringYesInternal ID of the transaction
transactionTypestringNoType of transaction (default: purchaseOrder)

Supported Transaction Types

  • purchaseOrder - Purchase Orders
  • salesOrder - Sales Orders
  • invoice - Invoices
  • vendorBill - Vendor Bills
  • estimate - Estimates

Response Format

{
"status": "success",
"data": {
"success": True,
"totalRecords": 1,
"files": [
{
"fileId": "678765",
"fileName": "invoice.pdf",
"fileUrl": "/core/media/media.nl?id=678765&c=...",
"fileType": "_PDF"
}
]
}
}

Practical Examples

Get Files from a Purchase Order

def get_po_attachments(po_internal_id):
"""Get all files attached to a purchase order"""
result = run_connection_action(
"netsuite",
"search_transaction_files",
{
"transactionId": str(po_internal_id),
"transactionType": "purchaseOrder"
}
)

if result['status'] == 'success':
return result['data']['files']
return []

# Usage
files = get_po_attachments("670932")
for f in files:
print(f"{f['fileName']} - {f['fileType']}")

Get Files from an Invoice

result = run_connection_action(
"netsuite",
"search_transaction_files",
{
"transactionId": "123456",
"transactionType": "invoice"
}
)

Download Attached File Content

import base64

# 1. Search for attached files
result = run_connection_action(
"netsuite",
"search_transaction_files",
{
"transactionId": "670932",
"transactionType": "purchaseOrder"
}
)

# 2. Download each file
for file in result['data']['files']:
file_details = run_connection_action(
"netsuite",
"get_file",
{"fileId": file['fileId']}
)

# Save to disk
content = file_details['data'].get('content')
if content:
with open(file['fileName'], 'wb') as f:
f.write(base64.b64decode(content))
print(f"Downloaded: {file['fileName']}")

Check if Transaction Has Attachments

def has_attachments(transaction_id, transaction_type="purchaseOrder"):
"""Check if a transaction has any file attachments"""
result = run_connection_action(
"netsuite",
"search_transaction_files",
{
"transactionId": str(transaction_id),
"transactionType": transaction_type
}
)

if result['status'] == 'success':
return len(result['data']['files']) > 0
return False

# Usage
if has_attachments("670932"):
print("PO has attachments")
else:
print("PO has no attachments")

Process Multiple Transactions

def get_attachments_for_transactions(transaction_ids, transaction_type="purchaseOrder"):
"""Get attachments for multiple transactions"""
all_attachments = {}

for trans_id in transaction_ids:
result = run_connection_action(
"netsuite",
"search_transaction_files",
{
"transactionId": str(trans_id),
"transactionType": transaction_type
}
)

if result['status'] == 'success':
all_attachments[trans_id] = result['data']['files']

return all_attachments

# Usage
po_ids = ["670932", "670933", "670934"]
attachments = get_attachments_for_transactions(po_ids)

for po_id, files in attachments.items():
print(f"PO {po_id}: {len(files)} files")

Building Full File URLs

The fileUrl returned is a relative path. To build the full URL:

def get_full_file_url(account_id, relative_url):
"""Convert relative URL to full NetSuite URL"""
return f"https://{account_id}.app.netsuite.com{relative_url}"

# Example
account_id = "1234567"
file_url = "/core/media/media.nl?id=678765&c=1234567&h=abc123"
full_url = get_full_file_url(account_id, file_url)
print(f"Full URL: {full_url}")

Error Handling

result = run_connection_action(
"netsuite",
"search_transaction_files",
{
"transactionId": "670932",
"transactionType": "purchaseOrder"
}
)

if result['status'] == 'error':
print(f"Error: {result['message']}")
elif result['data']['success']:
files = result['data']['files']
if files:
print(f"Found {len(files)} files")
else:
print("No files attached to this transaction")
else:
print("Search failed")

Troubleshooting

"Action search_transaction_files not found"

  • Enable soap resource in your NetSuite connection configuration

Empty Results

  • Verify the transaction ID is correct
  • Check that the transaction type matches
  • Confirm files were attached (not just referenced)

Permission Errors

  • Ensure the NetSuite role has Transaction Search permissions
  • Verify the token has access to the transaction type
FeatureSuiteQL (query)SOAP (search_transaction_files)
Files via Communication subtabYesYes
Files via SOAP attachNoYes
Query flexibilityHighLimited to transaction + files
PerformanceFasterSlower

Use search_transaction_files when:

  • Files were attached using the SOAP attach action
  • SuiteQL queries return empty for known attachments

Use SuiteQL query when:

  • Files were attached via NetSuite UI (Communication subtab)
  • You need complex filtering or joins

Next Steps