Skip to main content

Overview

The /api/get-context-upload endpoint allows you to fetch competition context using your own Kaggle API credentials. This is required for:
  • Private competitions
  • Competitions with restricted data access
  • Rate limit avoidance (uses your personal Kaggle quota)
Endpoint: POST /api/get-context-upload Content-Type: multipart/form-data Authentication: Not required (credentials provided in request)
Your kaggle.json file contains sensitive API credentials. Never commit it to version control or share it publicly.

Request

This endpoint uses multipart/form-data to accept file uploads.
url
string
required
Full Kaggle competition URL
top_n
integer
default:3
Number of top notebooks to include (1-10)
token_file
file
required
Your kaggle.json credentials file containing username and key

Getting your kaggle.json

1

Log in to Kaggle

Go to kaggle.com and sign in
2

Access your account settings

Click your profile picture → Settings
3

Create new API token

Scroll to API section → Click Create New Token
4

Download kaggle.json

Your browser will download kaggle.json automatically
The file format:
{
  "username": "your-kaggle-username",
  "key": "your-api-key-here"
}

Response

Returns a CompetitionResponse with processing status, as the ingestion happens in the background.
slug
string
Competition slug extracted from the URL
title
string
Always “Processing…” during initial request
status
string
Always processing (background task started)
message
string
Confirmation message: “Private ingestion started with provided credentials.”

Examples

cURL

curl -X POST http://localhost:8000/api/get-context-upload \
  -F "url=https://www.kaggle.com/competitions/private-competition" \
  -F "top_n=5" \
  -F "token_file=@/path/to/kaggle.json"

Python

import requests

with open('kaggle.json', 'rb') as f:
    files = {'token_file': f}
    data = {
        'url': 'https://www.kaggle.com/competitions/my-private-comp',
        'top_n': 3
    }
    
    response = requests.post(
        'http://localhost:8000/api/get-context-upload',
        files=files,
        data=data
    )
    
    result = response.json()
    print(f"Status: {result['status']}")
    print(f"Message: {result['message']}")
    print(f"Slug: {result['slug']}")

JavaScript (Browser)

const formData = new FormData();
formData.append('url', 'https://www.kaggle.com/competitions/private-comp');
formData.append('top_n', '5');
formData.append('token_file', fileInput.files[0]); // from <input type="file">

const response = await fetch('http://localhost:8000/api/get-context-upload', {
  method: 'POST',
  body: formData
});

const data = await response.json();
console.log(data.message); // "Private ingestion started with provided credentials."

Background processing

Unlike the public endpoints, this always triggers background processing:
1

Submit credentials

POST your URL and kaggle.json file
2

Receive processing status

Get immediate response with processing status
3

Wait 30-60 seconds

Background job fetches competition data using your credentials
4

Check status

Use GET /api/competitions/{slug} to check if processing completed
5

Retrieve results

Once status is completed, the toon_content field contains your data

Credential validation

The endpoint validates your kaggle.json before accepting the request:
# From backend/services/validation_service.py
async def validate_and_read_token_file(token_file: UploadFile) -> dict:
    """Validates kaggle.json structure"""
    content = await token_file.read()
    data = json.loads(content)
    
    if "username" not in data or "key" not in data:
        raise HTTPException(400, "Invalid kaggle.json format")
    
    return data

Security considerations

Your credentials are never stored. They’re used only for the immediate ingestion task and discarded afterward.
  • Credentials are validated but not persisted to the database
  • Used only in the background task context
  • Recommend rotating your Kaggle API token after use
  • KaggleIngest does not log credential contents

Error responses

400
error
Invalid kaggle.json format or missing required fields
{
  "detail": "Invalid kaggle.json format"
}
422
error
Missing file or invalid form data
{
  "detail": [
    {
      "loc": ["body", "token_file"],
      "msg": "field required",
      "type": "value_error.missing"
    }
  ]
}

Checking completion status

After submitting, poll the competition endpoint:
import time
import requests

# 1. Submit with credentials
response = requests.post(
    'http://localhost:8000/api/get-context-upload',
    files={'token_file': open('kaggle.json', 'rb')},
    data={'url': 'https://kaggle.com/c/private-comp', 'top_n': 3}
)
slug = response.json()['slug']

# 2. Poll for completion
for attempt in range(12):  # 2 minutes max
    time.sleep(10)
    
    status_resp = requests.get(f'http://localhost:8000/api/competitions/{slug}')
    data = status_resp.json()
    
    if data['status'] == 'completed':
        print("Success! Context ready:")
        print(data['toon_content'])
        break
    elif data['status'] == 'failed':
        print(f"Failed: {data.get('message')}")
        break
    else:
        print(f"Attempt {attempt + 1}: Still processing...")

Public competitions

Use the public endpoint for non-private competitions

Check status

Poll for completion status

Build docs developers (and LLMs) love