Add comprehensive API v1 with OAuth and API key authentication #2389

Merged
Shpigford merged 11 commits from api into main 2025-06-18 04:57:05 +08:00
Shpigford commented 2025-06-18 04:17:55 +08:00 (Migrated from github.com)

Summary

  • Implements a comprehensive API v1 with both OAuth2 and API key authentication
  • Adds accounts and transactions endpoints with full CRUD support
  • Includes rate limiting, usage tracking, and developer-friendly features

Key Features

Authentication & Authorization

  • OAuth2 Support: Full Doorkeeper integration for third-party apps
  • API Keys: JWT-based API keys with scoped permissions (read/read_write)
  • Dual Authentication: Supports both OAuth tokens and API keys seamlessly
  • Rate Limiting: Configurable limits per API key with Rack Attack integration

API Endpoints

  • Accounts (GET /api/v1/accounts): List user accounts with pagination
  • Transactions (GET/POST/PUT/DELETE /api/v1/transactions): Full CRUD with advanced filtering
    • Filter by account, category, merchant, date range, amount range, tags
    • Full-text search support
    • Pagination with metadata
  • Usage (GET /api/v1/usage): Track API usage and rate limit status

Developer Experience

  • JSON API: Clean JSON responses using Jbuilder templates
  • Error Handling: Consistent error responses with appropriate HTTP codes
  • API Key Management: User-friendly UI for creating and managing API keys
  • Documentation: Test endpoints for developers to validate their integration
  • Pagination: Standard pagination with metadata for all list endpoints

Security & Performance

  • Strong Parameters: Proper input validation and sanitization
  • Scoped Access: Read vs read/write permissions
  • Rate Limiting: Protects API from abuse
  • N+1 Prevention: Optimized queries with proper includes

Test Coverage

  • Comprehensive controller tests for all endpoints
  • API key and OAuth authentication tests
  • Rate limiting integration tests
  • System tests for API key management UI

Breaking Changes

None - this is a new API version that doesn't affect existing functionality.

Next Steps

After this PR, we can add more endpoints for:

  • Categories and tags management
  • Account details and balance history
  • Budget and reporting endpoints
  • Investment holdings and trades

🤖 Generated with Claude Code

Co-Authored-By: Claude noreply@anthropic.com

## Summary - Implements a comprehensive API v1 with both OAuth2 and API key authentication - Adds accounts and transactions endpoints with full CRUD support - Includes rate limiting, usage tracking, and developer-friendly features ## Key Features ### Authentication & Authorization - **OAuth2 Support**: Full Doorkeeper integration for third-party apps - **API Keys**: JWT-based API keys with scoped permissions (read/read_write) - **Dual Authentication**: Supports both OAuth tokens and API keys seamlessly - **Rate Limiting**: Configurable limits per API key with Rack Attack integration ### API Endpoints - **Accounts** (`GET /api/v1/accounts`): List user accounts with pagination - **Transactions** (`GET/POST/PUT/DELETE /api/v1/transactions`): Full CRUD with advanced filtering - Filter by account, category, merchant, date range, amount range, tags - Full-text search support - Pagination with metadata - **Usage** (`GET /api/v1/usage`): Track API usage and rate limit status ### Developer Experience - **JSON API**: Clean JSON responses using Jbuilder templates - **Error Handling**: Consistent error responses with appropriate HTTP codes - **API Key Management**: User-friendly UI for creating and managing API keys - **Documentation**: Test endpoints for developers to validate their integration - **Pagination**: Standard pagination with metadata for all list endpoints ### Security & Performance - **Strong Parameters**: Proper input validation and sanitization - **Scoped Access**: Read vs read/write permissions - **Rate Limiting**: Protects API from abuse - **N+1 Prevention**: Optimized queries with proper includes ## Test Coverage - Comprehensive controller tests for all endpoints - API key and OAuth authentication tests - Rate limiting integration tests - System tests for API key management UI ## Breaking Changes None - this is a new API version that doesn't affect existing functionality. ## Next Steps After this PR, we can add more endpoints for: - Categories and tags management - Account details and balance history - Budget and reporting endpoints - Investment holdings and trades 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
albertorizzi commented 2025-06-18 04:59:05 +08:00 (Migrated from github.com)

Thank @Shpigford for this implementation, it's one of the most useful features! As I keep experimenting with Maybe, I find it more and more useful and interesting! I hope it will be available also in self-hosted!

Thank @Shpigford for this implementation, it's one of the most useful features! As I keep experimenting with Maybe, I find it more and more useful and interesting! I hope it will be available also in self-hosted!
mercierv commented 2025-07-15 15:29:52 +08:00 (Migrated from github.com)

Hey guys, quick question, is there any swagger somewhere on how to use the API ? I mean for GET is fine, but I'd love to have some docs on how to POST, PUT for example :)
Thanks in advance

Hey guys, quick question, is there any swagger somewhere on how to use the API ? I mean for GET is fine, but I'd love to have some docs on how to POST, PUT for example :) Thanks in advance
Shpigford commented 2025-07-15 18:00:50 +08:00 (Migrated from github.com)

Hey guys, quick question, is there any swagger somewhere on how to use the API ? I mean for GET is fine, but I'd love to have some docs on how to POST, PUT for example :) Thanks in advance

@mercierv Not at the moment as we haven't officially launched it. 🤫

> Hey guys, quick question, is there any swagger somewhere on how to use the API ? I mean for GET is fine, but I'd love to have some docs on how to POST, PUT for example :) Thanks in advance @mercierv Not at the moment as we haven't officially launched it. 🤫
mercierv commented 2025-07-15 19:05:34 +08:00 (Migrated from github.com)

Hey guys, quick question, is there any swagger somewhere on how to use the API ? I mean for GET is fine, but I'd love to have some docs on how to POST, PUT for example :) Thanks in advance

@mercierv Not at the moment as we haven't officially launched it. 🤫

Dang :/ but I understand :) thanks

> > Hey guys, quick question, is there any swagger somewhere on how to use the API ? I mean for GET is fine, but I'd love to have some docs on how to POST, PUT for example :) Thanks in advance > > @mercierv Not at the moment as we haven't officially launched it. 🤫 Dang :/ but I understand :) thanks
mercierv commented 2025-07-16 13:44:13 +08:00 (Migrated from github.com)

Hey guys, quick question, is there any swagger somewhere on how to use the API ? I mean for GET is fine, but I'd love to have some docs on how to POST, PUT for example :) Thanks in advance

@mercierv Not at the moment as we haven't officially launched it. 🤫

Is there any way you guys could still help me figure out what are the mandatory parameter for creating a transaction ? 🙈 and I suppose it's a basic JSON body....
Cheers

> > Hey guys, quick question, is there any swagger somewhere on how to use the API ? I mean for GET is fine, but I'd love to have some docs on how to POST, PUT for example :) Thanks in advance > > @mercierv Not at the moment as we haven't officially launched it. 🤫 Is there any way you guys could still help me figure out what are the mandatory parameter for creating a transaction ? 🙈 and I suppose it's a basic JSON body.... Cheers
vinteo commented 2025-07-16 13:56:21 +08:00 (Migrated from github.com)

Is there any way you guys could still help me figure out what are the mandatory parameter for creating a transaction ? 🙈 and I suppose it's a basic JSON body.... Cheers

this worked for me, I fed the api code into AI and asked it to figure it out for me lol.

{
  "transaction": {
    "account_id": "2980ffb0-f595-4572-be0e-7b9b9c53949b",  // required
    "name": "test",  // required
    "date": "2025-07-15",  // required
    "amount": 100, // optional, defaults to 0
    "currency": "AUD", // optional, defaults to your profile I think
    "nature": "expense" // optional, defaults to `expense`, other option is `income`
  }
}

there is also category_id, merchant_id (single uuid) and tag_ids (array of uuids), notes, description (string) but I didn't test all of these.

> Is there any way you guys could still help me figure out what are the mandatory parameter for creating a transaction ? 🙈 and I suppose it's a basic JSON body.... Cheers this worked for me, I fed the api code into AI and asked it to figure it out for me lol. ```js { "transaction": { "account_id": "2980ffb0-f595-4572-be0e-7b9b9c53949b", // required "name": "test", // required "date": "2025-07-15", // required "amount": 100, // optional, defaults to 0 "currency": "AUD", // optional, defaults to your profile I think "nature": "expense" // optional, defaults to `expense`, other option is `income` } } ``` there is also `category_id`, `merchant_id` (single uuid) and `tag_ids` (array of uuids), `notes`, `description` (string) but I didn't test all of these.
mercierv commented 2025-07-16 13:58:12 +08:00 (Migrated from github.com)

Is there any way you guys could still help me figure out what are the mandatory parameter for creating a transaction ? 🙈 and I suppose it's a basic JSON body.... Cheers

this worked for me, I fed the api code into AI and asked it to figure it out for me lol.

{
  "transaction": {
    "account_id": "2980ffb0-f595-4572-be0e-7b9b9c53949b",  // required
    "name": "test",  // required
    "date": "2025-07-15",  // required
    "amount": 100, // optional, defaults to 0
    "currency": "AUD", // optional, defaults to your profile I think
    "nature": "expense" // optional, defaults to `expense`, other option is `income`
  }
}

there is also category_id, merchant_id (single uuid) and tag_ids (array of uuids), notes, description (string) but I didn't test all of these.

Man ! you're awesome, I will try this during the day. Cheers mate

> > Is there any way you guys could still help me figure out what are the mandatory parameter for creating a transaction ? 🙈 and I suppose it's a basic JSON body.... Cheers > > this worked for me, I fed the api code into AI and asked it to figure it out for me lol. > > ```js > { > "transaction": { > "account_id": "2980ffb0-f595-4572-be0e-7b9b9c53949b", // required > "name": "test", // required > "date": "2025-07-15", // required > "amount": 100, // optional, defaults to 0 > "currency": "AUD", // optional, defaults to your profile I think > "nature": "expense" // optional, defaults to `expense`, other option is `income` > } > } > ``` > > there is also `category_id`, `merchant_id` (single uuid) and `tag_ids` (array of uuids), `notes`, `description` (string) but I didn't test all of these. Man ! you're awesome, I will try this during the day. Cheers mate
mercierv commented 2025-07-16 21:31:28 +08:00 (Migrated from github.com)

Is there any way you guys could still help me figure out what are the mandatory parameter for creating a transaction ? 🙈 and I suppose it's a basic JSON body.... Cheers

this worked for me, I fed the api code into AI and asked it to figure it out for me lol.

{
  "transaction": {
    "account_id": "2980ffb0-f595-4572-be0e-7b9b9c53949b",  // required
    "name": "test",  // required
    "date": "2025-07-15",  // required
    "amount": 100, // optional, defaults to 0
    "currency": "AUD", // optional, defaults to your profile I think
    "nature": "expense" // optional, defaults to `expense`, other option is `income`
  }
}

there is also category_id, merchant_id (single uuid) and tag_ids (array of uuids), notes, description (string) but I didn't test all of these.

I've been testing it and it works like a charm. Only thing missing now is the ability to have a list of all the category ID :) Thanks again

> > Is there any way you guys could still help me figure out what are the mandatory parameter for creating a transaction ? 🙈 and I suppose it's a basic JSON body.... Cheers > > this worked for me, I fed the api code into AI and asked it to figure it out for me lol. > > ```js > { > "transaction": { > "account_id": "2980ffb0-f595-4572-be0e-7b9b9c53949b", // required > "name": "test", // required > "date": "2025-07-15", // required > "amount": 100, // optional, defaults to 0 > "currency": "AUD", // optional, defaults to your profile I think > "nature": "expense" // optional, defaults to `expense`, other option is `income` > } > } > ``` > > there is also `category_id`, `merchant_id` (single uuid) and `tag_ids` (array of uuids), `notes`, `description` (string) but I didn't test all of these. I've been testing it and it works like a charm. Only thing missing now is the ability to have a list of all the category ID :) Thanks again
gianniskotsas commented 2025-07-22 17:32:09 +08:00 (Migrated from github.com)

Is there any way you guys could still help me figure out what are the mandatory parameter for creating a transaction ? 🙈 and I suppose it's a basic JSON body.... Cheers

this worked for me, I fed the api code into AI and asked it to figure it out for me lol.

{
  "transaction": {
    "account_id": "2980ffb0-f595-4572-be0e-7b9b9c53949b",  // required
    "name": "test",  // required
    "date": "2025-07-15",  // required
    "amount": 100, // optional, defaults to 0
    "currency": "AUD", // optional, defaults to your profile I think
    "nature": "expense" // optional, defaults to `expense`, other option is `income`
  }
}

there is also category_id, merchant_id (single uuid) and tag_ids (array of uuids), notes, description (string) but I didn't test all of these.

Quick question, did you manage in any way to create transactions in bulk?

> > Is there any way you guys could still help me figure out what are the mandatory parameter for creating a transaction ? 🙈 and I suppose it's a basic JSON body.... Cheers > > this worked for me, I fed the api code into AI and asked it to figure it out for me lol. > > ```js > { > "transaction": { > "account_id": "2980ffb0-f595-4572-be0e-7b9b9c53949b", // required > "name": "test", // required > "date": "2025-07-15", // required > "amount": 100, // optional, defaults to 0 > "currency": "AUD", // optional, defaults to your profile I think > "nature": "expense" // optional, defaults to `expense`, other option is `income` > } > } > ``` > > there is also `category_id`, `merchant_id` (single uuid) and `tag_ids` (array of uuids), `notes`, `description` (string) but I didn't test all of these. Quick question, did you manage in any way to create transactions in bulk?
vinteo commented 2025-07-22 19:09:12 +08:00 (Migrated from github.com)

Not with a single call no, I don't think it is possible currently.

Not with a single call no, I don't think it is possible currently.
mercierv commented 2025-07-22 19:12:14 +08:00 (Migrated from github.com)

Is there any way you guys could still help me figure out what are the mandatory parameter for creating a transaction ? 🙈 and I suppose it's a basic JSON body.... Cheers

this worked for me, I fed the api code into AI and asked it to figure it out for me lol.

{
  "transaction": {
    "account_id": "2980ffb0-f595-4572-be0e-7b9b9c53949b",  // required
    "name": "test",  // required
    "date": "2025-07-15",  // required
    "amount": 100, // optional, defaults to 0
    "currency": "AUD", // optional, defaults to your profile I think
    "nature": "expense" // optional, defaults to `expense`, other option is `income`
  }
}

there is also category_id, merchant_id (single uuid) and tag_ids (array of uuids), notes, description (string) but I didn't test all of these.

Quick question, did you manage in any way to create transactions in bulk?

Nha was not able to unfortunately. But I use n8n for setting up transaction, so it's in bulk in a sens but transaction per transaction

> > > Is there any way you guys could still help me figure out what are the mandatory parameter for creating a transaction ? 🙈 and I suppose it's a basic JSON body.... Cheers > > > > > > this worked for me, I fed the api code into AI and asked it to figure it out for me lol. > > ```js > > { > > "transaction": { > > "account_id": "2980ffb0-f595-4572-be0e-7b9b9c53949b", // required > > "name": "test", // required > > "date": "2025-07-15", // required > > "amount": 100, // optional, defaults to 0 > > "currency": "AUD", // optional, defaults to your profile I think > > "nature": "expense" // optional, defaults to `expense`, other option is `income` > > } > > } > > ``` > > > > > > > > > > > > > > > > > > > > > > > > there is also `category_id`, `merchant_id` (single uuid) and `tag_ids` (array of uuids), `notes`, `description` (string) but I didn't test all of these. > > Quick question, did you manage in any way to create transactions in bulk? Nha was not able to unfortunately. But I use n8n for setting up transaction, so it's in bulk in a sens but transaction per transaction
gianniskotsas commented 2025-07-22 19:19:56 +08:00 (Migrated from github.com)

Is there any way you guys could still help me figure out what are the mandatory parameter for creating a transaction ? 🙈 and I suppose it's a basic JSON body.... Cheers

this worked for me, I fed the api code into AI and asked it to figure it out for me lol.

{
  "transaction": {
    "account_id": "2980ffb0-f595-4572-be0e-7b9b9c53949b",  // required
    "name": "test",  // required
    "date": "2025-07-15",  // required
    "amount": 100, // optional, defaults to 0
    "currency": "AUD", // optional, defaults to your profile I think
    "nature": "expense" // optional, defaults to `expense`, other option is `income`
  }
}

there is also category_id, merchant_id (single uuid) and tag_ids (array of uuids), notes, description (string) but I didn't test all of these.

Quick question, did you manage in any way to create transactions in bulk?

Nha was not able to unfortunately. But I use n8n for setting up transaction, so it's in bulk in a sens but transaction per transaction

Gotcha! Yeah, I did the same by setting up a n8n workflow as well. Seems to work like a charm. Too bad that gocardless has strict rate limits (4 requests per day) and can't test it now that I finished it because I already hit my rate limits during dev haha.

> > > > Is there any way you guys could still help me figure out what are the mandatory parameter for creating a transaction ? 🙈 and I suppose it's a basic JSON body.... Cheers > > > > > > > > > this worked for me, I fed the api code into AI and asked it to figure it out for me lol. > > > ```js > > > { > > > "transaction": { > > > "account_id": "2980ffb0-f595-4572-be0e-7b9b9c53949b", // required > > > "name": "test", // required > > > "date": "2025-07-15", // required > > > "amount": 100, // optional, defaults to 0 > > > "currency": "AUD", // optional, defaults to your profile I think > > > "nature": "expense" // optional, defaults to `expense`, other option is `income` > > > } > > > } > > > ``` > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > there is also `category_id`, `merchant_id` (single uuid) and `tag_ids` (array of uuids), `notes`, `description` (string) but I didn't test all of these. > > > > > > Quick question, did you manage in any way to create transactions in bulk? > > Nha was not able to unfortunately. But I use n8n for setting up transaction, so it's in bulk in a sens but transaction per transaction Gotcha! Yeah, I did the same by setting up a n8n workflow as well. Seems to work like a charm. Too bad that gocardless has strict rate limits (4 requests per day) and can't test it now that I finished it because I already hit my rate limits during dev haha.
Sign in to join this conversation.