What you are building
By the end of this tutorial, you have a working Python project that:- Authenticates to Box and reads an NDA stored in a Box folder.
- Defines a clause-extraction schema for governing law, term, termination, confidentiality period, and liability cap.
- Calls the POST /2.0/ai/extract_structured endpoint with confidence scores and source references enabled.
- Applies a simple, transparent rule set to score each clause and assemble a Deal Risk Summary in JSON and markdown.
- Uploads the summary back to Box as a companion file, so the analysis lives alongside the source document.
schema.py to match the clauses you care about.Why extract instead of prompting
A free-form prompt asks the model to decide what to return and how to format it, so the response shape drifts between documents and runs. Structured extraction inverts that: you declare the fields, and Box AI fills them in.Prerequisites
Before you start, make sure you have the following:- A free , which gives you access to the Box AI API.
- A Box application configured with Client Credentials Grant authentication.
- Python 3.11 or higher.
- An NDA uploaded to Box. You can download a and upload it to a Box folder. Note its file ID from the URL. For example, if the URL is
https://app.box.com/file/123456789, the file ID is123456789. Because a Client Credentials Grant app authenticates as a separate service account, add that service account as a collaborator with the Editor role on the file (or its parent folder) so it can read the NDA. You find the service account email in the Authenticate the Box client step. - A Box folder where the service account can write the summary, with the same service account added as an Editor collaborator. Note its folder ID from the URL.
- The following scopes enabled on your app:
- Read and write all files and folders stored in Box
- Manage AI
Step-by-step process
This tutorial uses two Box Platform capabilities:Set up the development environment
- Open your terminal and create a new project directory:
- Create and activate a Python virtual environment:
(.venv) at the beginning. This confirms you are working inside the virtual environment.source .venv/bin/activate from the project directory. If you see ModuleNotFoundError when running commands, it usually means the venv is not activated.- Install the required packages:
boxsdk gives you the box_sdk_gen module used throughout this tutorial. Confidence scores and source references are available directly on the SDK’s create_ai_extract_structured method through the include_confidence_score and include_reference parameters.- Create a
.envfile to store your credentials, then add the following content. Replace the placeholder values with your actual credentials from the Box Developer Console:
Authenticate the Box client
box_client.py and add the following code. It builds an authenticated client that you use to call Box AI and the uploads API through the SDK.Define the clause schema
schema.py and add the following code. Each field tells Box AI exactly what to look for. The prompt on each field adds context that improves accuracy on dense legal language. The fields are CreateAiExtractStructuredFields objects that you pass directly to the SDK’s extraction call in the next step.Extract the clauses
extract.py and add the following code. It uses the SDK’s create_ai_extract_structured method to send the schema to Box AI and asks for confidence scores and source references alongside the extracted values.answerholds the extracted value for each field.confidence_scoreholds alevel(LOW,MEDIUM, orHIGH) and a numericscorebetween 0 and 1 for each field.referenceholds the source text and its location in the document for each field.
reference returns the exact snippet and location Box AI used for each field. Its contents are passed straight through into your summary file in a later step so a reviewer can trace every value back to the source. For background, see the changelog entry.Score risk and build the summary
risk.py and add the following code. It applies a small, transparent rule set to each clause, assigns a severity, and assembles the Deal Risk Summary as a dictionary. It also renders a markdown version for humans.Save the summary back to Box
app.py and add the following code. It runs the extraction, builds the summary, and uploads both the JSON and markdown versions to your output folder as companion files.client.uploads.upload_file_version(file_id, ...) instead, but note that replacing a PDF with a markdown or JSON body changes the file’s type.Run the extraction
nda-risk-summary directory with the virtual environment activated, then run the script:reference object is omitted here for brevity):NDA-123456789-risk-summary.json and NDA-123456789-risk-summary.md, sitting alongside your other content and ready for review.Troubleshooting
ModuleNotFoundError: No module named '...'
ModuleNotFoundError: No module named '...'
source .venv/bin/activate from the project directory before running any python3 commands. Each new terminal tab needs its own activation.invalid_client: The client credentials are invalid
invalid_client: The client credentials are invalid
.env file:- Verify
BOX_CLIENT_IDandBOX_CLIENT_SECRETmatch the values in Developer Console > Configuration. - Confirm
BOX_ENTERPRISE_IDis your enterprise ID. - Ensure your app is authorized in the Developer Console and uses Client Credentials Grant.
404 Not Found
404 Not Found
confidence_score or reference is empty in the response
confidence_score or reference is empty in the response
include_confidence_score and include_reference to True, as shown in extract.py. Confidence estimation also depends on the model behind the extraction agent - see .409 Item with the same name already exists
409 Item with the same name already exists
app.py uploads the summary using a deterministic name derived from the file ID (for example, NDA-123456789-risk-summary.json), so running the script again against the same output folder tries to create files that are already there. Delete the previous -risk-summary.json and -risk-summary.md files from the output folder, or point OUTPUT_FOLDER_ID at a different folder, before re-running.Scaling to production
Trigger the summary automatically on upload
Trigger the summary automatically on upload
Route low-confidence clauses to human review
Route low-confidence clauses to human review
Handle complex or scanned documents
Handle complex or scanned documents
ai_agent_info.models in the response.Make summaries searchable with metadata
Make summaries searchable with metadata
Next steps
Supplier agreement extraction
struct and table field types.