By design, this endpoint can create new rows when keyColumns is set and as long as we pass rows that have values in keyColumns which do not match any existing rows.
So why doesn’t the API return addedRowIds in this case?
As a suggestion, it would have been much more helpful if this endpoint always returned two keys:
addedRowIds : empty Array if no rows are added. otherwise per above
updatedRowIds: similar idea, and also return an empty Array if no rows were updated.
This would be much more helpful for downstream processing of the response.
Hi @Nad - Thanks for the feedback, and I can see how it would be useful to have that information in all cases. I believe the reason we don’t return the added row IDs when key columns are set is due to the collaborative nature of a Coda document.
An edit to the document must be reconciled with the edits from other users / clients, which can take some time to complete. Rather than have your API request wait for that to finish, it instead just starts the process and returns a requestId. The getMutationStatus endpoint allows you to check when those asynchronous mutations have complete.
When you are only adding rows the API can go ahead and assign the new row IDs immediately, since it doesn’t matter what data is already in the table. However once you specify a key column it needs to compare your rows with those already in the doc, which means it needs to wait for the data to be reconciled before it knows which rows are new and which are updates.
I think we could in theory return the added rows IDs in the getMutationStatus result, but that information isn’t available today.
That makes sense @Eric_Koleda , thanks for the explanation.
I would be perfectly happy if getMutationsStatus endpoint returned addedRowIds (and ideally also updatedRowIds).
An alternative, which would probably require a lot more engineering, is to have separation of concerns:
a ‘insert many rows’ endpoint that only does bulk row inserts,
a ‘update many rows’ endpoint which takes an array of rowIds and does bulk updates. Currently the only way to update many rows is to repeatedly call the ‘update row’ endpoint, which is very slow due to so many round-trips to server and back.
I am building a python library for Coda (not yet published) and am loving the extensive API and the great documentation. However, I do find it lacking in ability to bulk query and bulk update rows by rowIDs, and I sincerely hope the team addresses this.
I think the existing upsertRows endpoint already meets the “insert many rows” scenario, but I can see how a bulk update endpoint would be useful. I’ll track that request, but I wouldn’t expect to see it actions in the near term.
I understand the need for async updates when upserting. However, I really think that the getMutationsStatus endpoint needs to return updatedRowIds. This would solve the issue I think.
I am having trouble to retrieve a newly created record (even if it is not created through upsert) so I’m not sure what is the solution for that. It can’t be that I can’t work with newly created records. It doesn’t give me back the ID nor appear when I search for it.
@Oren - Are you using the getMutationStatus endpoint to check when the upsert operation is complete? You’ll need to wait for the operation to complete before you can retrieve the newly created rows. Also, can you provide more context on why you need to add rows and retrieve them in quick succession?
Thank you for your continuing support. To be honest, I was really excited to move all my business’ data to Coda but after working a little bit with your API I realized that this is not workable and I honestly don’t understand why it is so.
Getting ID of a newly created record is pretty basic and I am not sure why I need to give an example but there you go: You create an order and you want to connect order items to it - so you create the order and then you create the order items with the order id. This is such a basic data functionality and in Coda it is a nightmare. Sometimes it takes the newly created record 30s (!) to be available via API again (I created it and waited for 20s and still it wasn’t available). This is not an acceptable behavior by the lowest standards. And don’t get me started about the filtering options when you try to search for specific records. Really, Eric, what is that? I feel like I wasted so much time on this platform and now it’s all for nothing as your API is not workable.
No filters
The rate limits are ridiculous (Writing data (POST/PUT/PATCH): 10 requests per 6 seconds - really?)
No returned ID
Up to 30 seconds until the data is available via API
I worked with dozens of systems and it was never that bad with any of them. I love so many things about Coda and I was really excited about it but this is just a huge HUGE bummer that I don’t see how I can keep working with it. I consulted a friend of mine to move to your platform from Airtable and now I feel that I gave really bad advice.
Is there any chance that these issues will be fixed?
Getting ID of a newly created record is pretty basic and I am not sure why I need to give an example
I agree that this is a very reasonable request, and something we should have already. However when it comes to prioritizing new work the first thing the product team asks is “What’s the use case?” How much that use case aligns with our vision for the product, and how critical the feature is for achieving that use case, help to shape the priority assigned.
You create an order and you want to connect order items to it - so you create the order and then you create the order items with the order id.
That makes sense, and I’ll pass that along to the team. You may be able to achieve this today if you make the unique external ID for your order the display column. Then when you insert the line item just use the order ID in the relation column, and it will link up, without needing to wait for the internal row ID.
I feel like I wasted so much time on this platform and now it’s all for nothing as your API is not workable.
I’m sorry to hear that, and I understand the frustration. We’ve certainly put a lot more attention into the user-facing side of the product (which I think it quite good, but I’m biased) and not quite as much on the developer-facing side. I’m hoping to change that over time, and feedback like yours helps me make that case.
One other thing to note: if you haven’t already you may want to look into building a Pack as an alternative approach to integrating Coda with your external systems. We’ve invested a ton into our Pack infrastructure over the last couple of years, and in many cases it can provide a better experience. Specifically, the sync table building block handles all of the row and column syncing automatically, and all you as the developer needs to do is provide the data. With the two-way sync feature you can make edits to the data in Coda and push those back to your external system.
Information that was updated manually will only be available to the API after 5-10 seconds.
The same goes for new columns in a table.
After you create a record via API it will be available only after 30-45 seconds (!)
The rate limits are absurdly low
This is not something that is workable for me and it seems that Coda doesn’t think it is a big deal. For me it is a huge deal, and now I have to stop developing on Coda unfortunately and take my customers out because I can’t provide them with stability and acceptable workflows (creating a simple report takes 60-75 seconds due to the lagging in the creation of a parent record and the extremely low rate limits).
I do pray that magically you will tell me that it will be solved in a few weeks but I know that won’t happen.
In any case I thank you for your kindness and detailed responses. Coda are lucky to have you.
I was confused too about the API and thought that the “Only applicable when keyColumns is not set or empty.” was outdated and it returned addedRowIds in both cases.
Maybe I should use a Pack with two-way sync but it was a nice feature in the beginning of our use case to import data manually from CSV and use it as a DB & source of truth while locking the doc to ensure no edits could be made unless by clicking on buttons.
Now I think the best way is to invert the sync order and use the insert/upsert blindly without checking if there are new or only updated rows, otherwise I would need to make a query for each row to check if it already exists and use the upsert endpoint once for existing rows and once for the new rows.
Also as @Oren suggested the API rate limit seems really low, when I hit it I have to wait 8 seconds and 4 times out of 5 it works, otherwise double wait. I have had two times a 504 Gateway Error and found out once that it still created the row, but I had no way of knowing it so the retry logic made a duplicate row and I had to add some logic to remove “dangling” rows, for a use case where a user can do certain actions on rows that represents issues to be solved.